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