1/* $NetBSD: init.c,v 1.2 2021/08/14 16:15:02 christos Exp $ */ 2 3/* OpenLDAP WiredTiger backend */ 4/* $OpenLDAP$ */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 2002-2021 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18/* ACKNOWLEDGEMENTS: 19 * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp> 20 * based on back-bdb for inclusion in OpenLDAP Software. 21 * WiredTiger is a product of MongoDB Inc. 22 */ 23 24#include <sys/cdefs.h> 25__RCSID("$NetBSD: init.c,v 1.2 2021/08/14 16:15:02 christos Exp $"); 26 27#include "portable.h" 28 29#include <stdio.h> 30#include <ac/string.h> 31#include "back-wt.h" 32#include "slap-config.h" 33 34static int 35wt_db_init( BackendDB *be, ConfigReply *cr ) 36{ 37 struct wt_info *wi; 38 39 Debug( LDAP_DEBUG_TRACE, 40 LDAP_XSTRING(wt_db_init) ": Initializing wt backend\n" ); 41 42 /* allocate backend-database-specific stuff */ 43 wi = ch_calloc( 1, sizeof(struct wt_info) ); 44 45 wi->wi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR ); 46 wi->wi_dbenv_config = ch_strdup("create"); 47 wi->wi_lastid = 0; 48 wi->wi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH; 49 wi->wi_search_stack = NULL; 50 51 be->be_private = wi; 52 be->be_cf_ocs = be->bd_info->bi_cf_ocs; 53 54 return LDAP_SUCCESS; 55} 56 57static int 58wt_db_open( BackendDB *be, ConfigReply *cr ) 59{ 60 struct wt_info *wi = (struct wt_info *) be->be_private; 61 int rc; 62 struct stat st; 63 WT_CONNECTION *conn; 64 WT_SESSION *session; 65 66 if ( be->be_suffix == NULL ) { 67 Debug( LDAP_DEBUG_ANY, 68 LDAP_XSTRING(wt_db_open) ": need suffix.\n" ); 69 return -1; 70 } 71 72 Debug( LDAP_DEBUG_ARGS, 73 LDAP_XSTRING(wt_db_open) ": \"%s\"\n", 74 be->be_suffix[0].bv_val ); 75 76 /* Check existence of home. Any error means trouble */ 77 rc = stat( wi->wi_dbenv_home, &st ); 78 if( rc ) { 79 int saved_errno = errno; 80 Debug( LDAP_DEBUG_ANY, 81 LDAP_XSTRING(wt_db_open) ": database \"%s\": " 82 "cannot access database directory \"%s\" (%d).\n", 83 be->be_suffix[0].bv_val, wi->wi_dbenv_home, saved_errno ); 84 return -1; 85 } 86 87 /* Open and create database */ 88 rc = wiredtiger_open(wi->wi_dbenv_home, NULL, 89 wi->wi_dbenv_config, &conn); 90 if( rc ) { 91 int saved_errno = errno; 92 Debug( LDAP_DEBUG_ANY, 93 LDAP_XSTRING(wt_db_open) ": database \"%s\": " 94 "cannot open database \"%s\" (%d).\n", 95 be->be_suffix[0].bv_val, wi->wi_dbenv_home, saved_errno ); 96 return -1; 97 } 98 99 rc = conn->open_session(conn, NULL, NULL, &session); 100 if( rc ) { 101 Debug( LDAP_DEBUG_ANY, 102 LDAP_XSTRING(wt_db_open) ": database \"%s\": " 103 "cannot open session: \"%s\"\n", 104 be->be_suffix[0].bv_val, wiredtiger_strerror(rc) ); 105 return -1; 106 } 107 108 rc = session->create(session, 109 WT_TABLE_ID2ENTRY, 110 "key_format=Q," 111 "value_format=Su," 112 "columns=(id,dn,entry)"); 113 if( rc ) { 114 Debug( LDAP_DEBUG_ANY, 115 LDAP_XSTRING(wt_db_open) ": database \"%s\": " 116 "cannot create entry table: \"%s\"\n", 117 be->be_suffix[0].bv_val, wiredtiger_strerror(rc) ); 118 return -1; 119 } 120 121 rc = session->create(session, 122 WT_TABLE_DN2ID, 123 "key_format=S," 124 "value_format=QQS," 125 "columns=(ndn,id,pid,revdn)"); 126 if( rc ) { 127 Debug( LDAP_DEBUG_ANY, 128 LDAP_XSTRING(wt_db_open) ": database \"%s\": " 129 "cannot create entry table: \"%s\"\n", 130 be->be_suffix[0].bv_val, wiredtiger_strerror(rc) ); 131 return -1; 132 } 133 134 /* not using dn2id index for id2entry table */ 135 rc = session->create(session, WT_INDEX_DN, "columns=(dn)"); 136 if( rc ) { 137 Debug( LDAP_DEBUG_ANY, 138 LDAP_XSTRING(wt_db_open) ": database \"%s\": " 139 "cannot create dn index: \"%s\"\n", 140 be->be_suffix[0].bv_val, wiredtiger_strerror(rc) ); 141 return -1; 142 } 143 144 rc = session->create(session, WT_INDEX_PID, "columns=(pid)"); 145 if( rc ) { 146 Debug( LDAP_DEBUG_ANY, 147 LDAP_XSTRING(wt_db_open) ": database \"%s\": " 148 "cannot create pid index: \"%s\"\n", 149 be->be_suffix[0].bv_val, wiredtiger_strerror(rc) ); 150 return -1; 151 } 152 153 rc = session->create(session, WT_INDEX_REVDN, "columns=(revdn)"); 154 if( rc ) { 155 Debug( LDAP_DEBUG_ANY, 156 LDAP_XSTRING(wt_db_open) ": database \"%s\": " 157 "cannot create revdn index: \"%s\"\n", 158 be->be_suffix[0].bv_val, wiredtiger_strerror(rc) ); 159 return -1; 160 } 161 162 rc = wt_last_id( be, session, &wi->wi_lastid); 163 if (rc) { 164 snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": " 165 "last_id() failed: %s(%d).", 166 be->be_suffix[0].bv_val, wiredtiger_strerror(rc), rc ); 167 Debug( LDAP_DEBUG_ANY, 168 LDAP_XSTRING(wt_db_open) ": %s\n", 169 cr->msg ); 170 return rc; 171 } 172 173 session->close(session, NULL); 174 wi->wi_conn = conn; 175 wi->wi_flags |= WT_IS_OPEN; 176 177 return LDAP_SUCCESS; 178} 179 180static int 181wt_db_close( BackendDB *be, ConfigReply *cr ) 182{ 183 struct wt_info *wi = (struct wt_info *) be->be_private; 184 int rc; 185 186 rc = wi->wi_conn->close(wi->wi_conn, NULL); 187 if( rc ) { 188 int saved_errno = errno; 189 Debug( LDAP_DEBUG_ANY, 190 LDAP_XSTRING(wt_db_close) 191 ": cannot close database (%d).\n", 192 saved_errno ); 193 return -1; 194 } 195 196 wi->wi_flags &= ~WT_IS_OPEN; 197 198 return LDAP_SUCCESS; 199} 200 201static int 202wt_db_destroy( Backend *be, ConfigReply *cr ) 203{ 204 struct wt_info *wi = (struct wt_info *) be->be_private; 205 206 if( wi->wi_dbenv_home ) { 207 ch_free( wi->wi_dbenv_home ); 208 wi->wi_dbenv_home = NULL; 209 } 210 if( wi->wi_dbenv_config ) { 211 ch_free( wi->wi_dbenv_config ); 212 wi->wi_dbenv_config = NULL; 213 } 214 215 wt_attr_index_destroy( wi ); 216 ch_free( wi ); 217 be->be_private = NULL; 218 219 return LDAP_SUCCESS; 220} 221 222int 223wt_back_initialize( BackendInfo *bi ) 224{ 225 static char *controls[] = { 226 LDAP_CONTROL_ASSERT, 227 LDAP_CONTROL_MANAGEDSAIT, 228 LDAP_CONTROL_NOOP, 229 LDAP_CONTROL_PAGEDRESULTS, 230 LDAP_CONTROL_PRE_READ, 231 LDAP_CONTROL_POST_READ, 232 LDAP_CONTROL_SUBENTRIES, 233 LDAP_CONTROL_X_PERMISSIVE_MODIFY, 234 NULL 235 }; 236 237 /* initialize the database system */ 238 Debug( LDAP_DEBUG_TRACE, 239 LDAP_XSTRING(wt_back_initialize) 240 ": initialize WiredTiger backend\n" ); 241 242 bi->bi_flags |= 243 SLAP_BFLAG_INCREMENT | 244 SLAP_BFLAG_SUBENTRIES | 245 SLAP_BFLAG_ALIASES | 246 SLAP_BFLAG_REFERRALS; 247 248 bi->bi_controls = controls; 249/* version check */ 250 Debug( LDAP_DEBUG_TRACE, 251 LDAP_XSTRING(wt_back_initialize) ": %s\n", 252 wiredtiger_version(NULL, NULL, NULL) ); 253 254 bi->bi_open = 0; 255 bi->bi_close = 0; 256 bi->bi_config = 0; 257 bi->bi_destroy = 0; 258 259 bi->bi_db_init = wt_db_init; 260 bi->bi_db_config = config_generic_wrapper; 261 bi->bi_db_open = wt_db_open; 262 bi->bi_db_close = wt_db_close; 263 bi->bi_db_destroy = wt_db_destroy; 264 265 bi->bi_op_add = wt_add; 266 bi->bi_op_bind = wt_bind; 267 bi->bi_op_unbind = 0; 268 bi->bi_op_search = wt_search; 269 bi->bi_op_compare = wt_compare; 270 bi->bi_op_modify = wt_modify; 271 bi->bi_op_modrdn = 0; 272 bi->bi_op_delete = wt_delete; 273 bi->bi_op_abandon = 0; 274 275 bi->bi_extended = 0; 276 277 bi->bi_chk_referrals = 0; 278 bi->bi_operational = wt_operational; 279 280 bi->bi_entry_release_rw = wt_entry_release; 281 bi->bi_entry_get_rw = wt_entry_get; 282 283 bi->bi_tool_entry_open = wt_tool_entry_open; 284 bi->bi_tool_entry_close = wt_tool_entry_close; 285 bi->bi_tool_entry_first = backend_tool_entry_first; 286 bi->bi_tool_entry_first_x = wt_tool_entry_first_x; 287 bi->bi_tool_entry_next = wt_tool_entry_next; 288 bi->bi_tool_entry_get = wt_tool_entry_get; 289 bi->bi_tool_entry_put = wt_tool_entry_put; 290 bi->bi_tool_entry_reindex = wt_tool_entry_reindex; 291 292 bi->bi_connection_init = 0; 293 bi->bi_connection_destroy = 0; 294 295 return wt_back_init_cf( bi ); 296} 297 298#if SLAPD_WT == SLAPD_MOD_DYNAMIC 299 300/* conditionally define the init_module() function */ 301SLAP_BACKEND_INIT_MODULE( wt ) 302 303#endif /* SLAPD_WT == SLAPD_MOD_DYNAMIC */ 304 305/* 306 * Local variables: 307 * indent-tabs-mode: t 308 * tab-width: 4 309 * c-basic-offset: 4 310 * End: 311 */ 312