1 /* txn.c - TP support functions of the bdb2 backend */
7 bdb2i_txn_head_init( BDB2_TXN_HEAD *head )
10 BDB2_TXN_FILES **fileNodeH;
12 /* for each fixed DB file allocate a file descriptor node and
13 initialize the file's name */
14 fileNodeH = &head->dbFiles;
15 for ( dbFile = BDB2_DB_DN_FILE; dbFile <= BDB2_DB_OC_IDX_FILE; dbFile++ ) {
17 char fileName[MAXPATHLEN];
19 *fileNodeH = (BDB2_TXN_FILES *) ch_calloc( 1, sizeof( BDB2_TXN_FILES ));
20 if ( *fileNodeH == NULL ) {
22 Debug( LDAP_DEBUG_ANY, "bdb2i_txn_head_init(): out of memory!\n",
28 sprintf( fileName, "%s%s", bdb2i_fixed_filenames[dbFile], LDBM_SUFFIX );
29 (*fileNodeH)->dbc_name = strdup( fileName );
31 fileNodeH = &(*fileNodeH)->next;
40 bdb2i_init_db_file_cache( struct ldbminfo *li, BDB2_TXN_FILES *fileinfo )
46 ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
47 curtime = currenttime;
48 ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
50 fileinfo->dbc_refcnt = 1;
51 fileinfo->dbc_lastref = curtime;
53 sprintf( buf, "%s%s%s", li->li_directory, DEFAULT_DIRSEP,
55 if ( stat( buf, &st ) == 0 ) {
56 fileinfo->dbc_blksize = st.st_blksize;
58 fileinfo->dbc_blksize = DEFAULT_BLOCKSIZE;
61 fileinfo->dbc_maxids = ( fileinfo->dbc_blksize / sizeof( ID )) -
63 fileinfo->dbc_maxindirect = ( SLAPD_LDBM_MIN_MAXIDS /
64 fileinfo->dbc_maxids ) + 1;
70 bdb2i_txn_attr_config(
75 BDB2_TXN_HEAD *head = &li->li_txn_head;
77 /* the "attribute" 'default' is special */
78 if ( strcasecmp( attr, "default" )) {
80 /* create a new index file node, if the index is not known already */
81 BDB2_TXN_FILES **fileNodeH;
82 char fileName[MAXPATHLEN];
84 sprintf( fileName, "%s%s", attr, LDBM_SUFFIX );
86 /* search for the end of the list or a node describing
87 the current attribute */
88 for ( fileNodeH = &head->dbFiles;
89 ( *fileNodeH && strcasecmp( (*fileNodeH)->dbc_name, fileName ));
90 fileNodeH = &(*fileNodeH)->next ) {
94 /* unless we have that attribute already... */
95 if ( *fileNodeH == NULL ) {
98 Debug( LDAP_DEBUG_TRACE,
99 "bdb2i_txn_attr_config(): adding node for \"%s\"\n",
102 /* if we're out of memory, we have to see, how to exit... */
103 if ( ( *fileNodeH = p = (BDB2_TXN_FILES *)
104 ch_calloc( 1, sizeof( BDB2_TXN_FILES )) ) == NULL ) {
106 Debug( LDAP_DEBUG_ANY,
107 "bdb2i_txn_attr_config(): out of memory -- FATAL.\n",
110 /* during configuration (no files are opened)
111 we can just exit, otherwise we kill ourself and
112 hope to shutdown cleanly... */
114 pthread_kill( pthread_self(), LDAP_SIGUSR1 );
120 p->dbc_name = strdup( fileName );
122 /* if requested for, we have to open the DB file */
123 /* BUT NOT "objectclass", 'cause that's a default index ! */
124 if ( open && strcasecmp( fileName, "objectclass" )) {
126 /* re-use filename to get the complete path */
127 sprintf( fileName, "%s%s%s",
128 li->li_directory, DEFAULT_DIRSEP, p->dbc_name );
130 /* since we have an mpool, we should not define a cache size */
131 p->dbc_db = ldbm_open( fileName, LDBM_WRCREAT, li->li_mode, 0 );
133 /* if the files could not be opened, something is wrong;
135 if ( p->dbc_db == NULL ) {
137 Debug( LDAP_DEBUG_ANY,
138 "bdb2i_txn_open_files(): couldn't open file \"%s\" -- FATAL.\n",
140 pthread_kill( pthread_self(), LDAP_SIGUSR1 );
144 bdb2i_init_db_file_cache( li, p );
146 Debug( LDAP_DEBUG_TRACE,
147 "bdb2i_txn_attr_config(): NEW INDEX FILE \"%s\"\n",
153 } else { /* it is "attribute" 'default' */
155 head->withDefIDX = BDB2_WITH_DEF_IDX;
162 bdb2i_txn_open_files( struct ldbminfo *li )
164 BDB2_TXN_HEAD *head = &li->li_txn_head;
165 BDB2_TXN_FILES *dbFile;
167 for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
168 char fileName[MAXPATHLEN];
170 sprintf( fileName, "%s%s%s",
171 li->li_directory, DEFAULT_DIRSEP, dbFile->dbc_name );
173 /* since we have an mpool, we should not define a cache size */
174 dbFile->dbc_db = ldbm_open( fileName, LDBM_WRCREAT, li->li_mode, 0 );
176 /* if the files could not be opened, something is wrong; complain */
177 if ( dbFile->dbc_db == NULL ) {
179 Debug( LDAP_DEBUG_ANY,
180 "bdb2i_txn_open_files(): couldn't open file \"%s\" -- FATAL.\n",
181 dbFile->dbc_name, 0, 0 );
186 /* initialize the file info */
187 bdb2i_init_db_file_cache( li, dbFile );
189 Debug( LDAP_DEBUG_TRACE, "bdb2i_txn_open_files(): OPEN INDEX \"%s\"\n",
190 dbFile->dbc_name, 0, 0 );
199 bdb2i_txn_close_files( BackendDB *be )
201 struct ldbminfo *li = (struct ldbminfo *) be->be_private;
202 BDB2_TXN_HEAD *head = &li->li_txn_head;
203 BDB2_TXN_FILES *dbFile;
205 for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
207 ldbm_close( dbFile->dbc_db );
214 bdb2i_get_db_file_cache( struct ldbminfo *li, char *name )
216 BDB2_TXN_HEAD *head = &li->li_txn_head;
217 BDB2_TXN_FILES *dbFile;
220 Debug( LDAP_DEBUG_TRACE, "bdb2i_get_db_file_cache(): looking for file %s\n",
223 for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
226 if ( !strcasecmp( dbFile->dbc_name, name )) return( dbFile );
230 Debug( LDAP_DEBUG_ANY,
231 "bdb2i_get_db_file_cache(): UPS, could't find \"%s\" \n", name, 0, 0 );
233 /* ups, we couldn't find the file */
239 /* check for new attribute indexes, that might have been created
240 during former runs of slapd */
241 /* this is called during startup of the slapd server */
243 bdb2i_check_additional_attr_index( struct ldbminfo *li )
248 if ( ( datadir = opendir( li->li_directory ) ) == NULL ) {
250 Debug( LDAP_DEBUG_ANY,
251 "bdb2i_check_additional_attr_index(): ERROR while opening datadir: %s\n",
252 strerror( errno ), 0, 0 );
257 for ( file = readdir( datadir ); file; file = readdir( datadir )) {
258 char filename[MAXPATHLEN];
261 strcpy( filename, file->d_name );
262 namelen = strlen( filename );
264 if ( namelen > strlen( LDBM_SUFFIX )) {
266 if ( !strcasecmp( filename + namelen - strlen( LDBM_SUFFIX ),
269 *(filename + namelen - strlen( LDBM_SUFFIX )) = '\0';
270 bdb2i_txn_attr_config( li, filename, 0 );
272 Debug( LDAP_DEBUG_TRACE, "INDEX FILE: %s\n", filename, 0, 0 );
286 /* check for the addition of new attribute indexes during add */
287 /* this is called after startup of the slapd server */
288 /* DON'T WORRY ABOUT ACCESS RIGHTS, THAT MIGHT PREVENT US
289 FROM ADDING ATTRIBUTES LATER ON */
291 bdb2i_check_default_attr_index_add( struct ldbminfo *li, Entry *e )
293 BDB2_TXN_HEAD *head = &li->li_txn_head;
295 if ( head->withDefIDX == BDB2_WITH_DEF_IDX ) {
298 for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
299 if ( strcasecmp( ap->a_type, "objectclass" ))
300 bdb2i_txn_attr_config( li, ap->a_type, 1 );
306 /* check for the addition of new attribute indexes during modify */
307 /* this is called after startup of the slapd server */
308 /* DON'T WORRY ABOUT ACCESS RIGHTS, THAT MIGHT PREVENT US
309 FROM ADDING ATTRIBUTES LATER ON */
311 bdb2i_check_default_attr_index_mod( struct ldbminfo *li, LDAPModList *modlist )
313 BDB2_TXN_HEAD *head = &li->li_txn_head;
315 if ( head->withDefIDX == BDB2_WITH_DEF_IDX ) {
317 char *default_attrs[] = { "modifytimestamp", "modifiersname", NULL };
320 for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
321 LDAPMod *mod = &ml->ml_mod;
323 if (( mod->mod_op & ~LDAP_MOD_BVALUES ) == LDAP_MOD_ADD )
324 if ( strcasecmp( mod->mod_type, "objectclass" ))
325 bdb2i_txn_attr_config( li, mod->mod_type, 1 );
328 /* these attributes are default when modifying */
329 for ( attr = 0; default_attrs[attr]; attr++ ) {
330 bdb2i_txn_attr_config( li, default_attrs[attr], 1 );