xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-wt/init.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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 
34 static int
wt_db_init(BackendDB * be,ConfigReply * cr)35 wt_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 
57 static int
wt_db_open(BackendDB * be,ConfigReply * cr)58 wt_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 
180 static int
wt_db_close(BackendDB * be,ConfigReply * cr)181 wt_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 
201 static int
wt_db_destroy(Backend * be,ConfigReply * cr)202 wt_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 
222 int
wt_back_initialize(BackendInfo * bi)223 wt_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 */
301 SLAP_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