]> git.proxmox.com Git - pve-cluster.git/blob - data/src/database.c
bump version to 8.0.6
[pve-cluster.git] / data / src / database.c
1 /*
2 Copyright (C) 2010 Proxmox Server Solutions GmbH
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Affero General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Affero General Public License for more details.
13
14 You should have received a copy of the GNU Affero General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 Author: Dietmar Maurer <dietmar@proxmox.com>
18
19 */
20
21 #define G_LOG_DOMAIN "database"
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif /* HAVE_CONFIG_H */
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <glib.h>
32 #include <dirent.h>
33 #include <sys/stat.h>
34 #include <errno.h>
35
36 #include <sqlite3.h>
37
38 #include "cfs-utils.h"
39 #include "status.h"
40 #include "memdb.h"
41
42 struct db_backend {
43 sqlite3 *db;
44 sqlite3_stmt *stmt_insert_entry;
45 sqlite3_stmt *stmt_update_entry;
46 sqlite3_stmt *stmt_replace_entry;
47 sqlite3_stmt *stmt_delete_entry;
48 sqlite3_stmt *stmt_begin;
49 sqlite3_stmt *stmt_commit;
50 sqlite3_stmt *stmt_rollback;
51 sqlite3_stmt *stmt_load_all;
52 };
53
54 #define VERSIONFILENAME "__version__"
55
56 /* colume type "INTEGER PRIMARY KEY" is a special case, because sqlite
57 * usese the internal ROWID. So only real interger are allowed, and
58 * there is no need to add an additionl check
59 */
60 static const char *sql_create_db =
61 "CREATE TABLE IF NOT EXISTS tree ("
62 " inode INTEGER PRIMARY KEY NOT NULL,"
63 " parent INTEGER NOT NULL CHECK(typeof(parent)=='integer'),"
64 " version INTEGER NOT NULL CHECK(typeof(version)=='integer'),"
65 " writer INTEGER NOT NULL CHECK(typeof(writer)=='integer'),"
66 " mtime INTEGER NOT NULL CHECK(typeof(mtime)=='integer'),"
67 " type INTEGER NOT NULL CHECK(typeof(type)=='integer'),"
68 " name TEXT NOT NULL,"
69 " data BLOB);";
70
71 static const char *sql_load_all =
72 "SELECT inode, parent, version, writer, mtime, type, name, data FROM tree;";
73
74 static char *sql_insert_entry =
75 "INSERT INTO tree ("
76 "inode, parent, version, writer, mtime, type, name, data) "
77 "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);";
78
79 static char *sql_update_entry =
80 "UPDATE tree SET parent = ?2, version = ?3, writer = ?4, mtime = ?5, "
81 "type = ?6, name = ?7, data = ?8 WHERE inode = ?1;";
82
83 static char *sql_replace_entry =
84 "REPLACE INTO tree (inode, parent, version, writer, mtime, type, "
85 "name, data) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);";
86
87 static char *sql_delete_entry =
88 "DELETE FROM tree WHERE inode = ?1;";
89
90 static char *sql_begin = "BEGIN TRANSACTION;";
91 static char *sql_commit = "COMMIT TRANSACTION;";
92 static char *sql_rollback = "ROLLBACK TRANSACTION;";
93
94 static sqlite3 *bdb_create(
95 const char *filename)
96 {
97 int rc;
98 sqlite3 *db = NULL;
99
100 int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
101 rc = sqlite3_open_v2(filename, &db, flags, NULL);
102 if (rc != SQLITE_OK) {
103 cfs_critical("splite3_open_v2 failed: %d\n", rc);
104 sqlite3_close(db);
105 return NULL;
106 }
107
108 if (chmod(filename, 0600) == -1) {
109 cfs_critical("chmod failed: %s", strerror(errno));
110 return NULL;
111 }
112
113 /* use WAL mode - to allow concurrent reads */
114 rc = sqlite3_exec(db, "PRAGMA journal_mode=WAL;", NULL, NULL, NULL);
115 if (rc != SQLITE_OK) {
116 cfs_critical("unable to set WAL mode: %s\n", sqlite3_errmsg(db));
117 sqlite3_close(db);
118 return NULL;
119 }
120
121 /* NORMAL is good enough when using WAL */
122 rc = sqlite3_exec(db, "PRAGMA synchronous=NORMAL", NULL, NULL, NULL);
123 if (rc != SQLITE_OK) {
124 cfs_critical("unable to set synchronous mode: %s\n", sqlite3_errmsg(db));
125 sqlite3_close(db);
126 return NULL;
127 }
128
129 sqlite3_busy_timeout(db, 10000); /* 10 seconds */
130
131 rc = sqlite3_exec(db, sql_create_db, NULL, NULL, NULL);
132 if (rc != SQLITE_OK) {
133 cfs_critical("init database failed: %s\n", sqlite3_errmsg(db));
134 sqlite3_close(db);
135 return NULL;
136 }
137
138 return db;
139 }
140
141 static int backend_write_inode(
142 sqlite3 *db,
143 sqlite3_stmt *stmt,
144 guint64 inode,
145 guint64 parent,
146 guint64 version,
147 guint32 writer,
148 guint32 mtime,
149 guint32 size,
150 char type,
151 char *name,
152 gpointer value)
153 {
154 int rc;
155
156 cfs_debug("enter backend_write_inode %016zX", inode);
157
158 if ((rc = sqlite3_bind_int64(stmt, 1, inode)) != SQLITE_OK) {
159 cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
160 return rc;
161 }
162 if ((rc = sqlite3_bind_int64(stmt, 2, parent)) != SQLITE_OK) {
163 cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
164 return rc;
165 }
166 if ((rc = sqlite3_bind_int64(stmt, 3, version)) != SQLITE_OK) {
167 cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
168 return rc;
169 }
170 if ((rc = sqlite3_bind_int64(stmt, 4, writer)) != SQLITE_OK) {
171 cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
172 return rc;
173 }
174 if ((rc = sqlite3_bind_int64(stmt, 5, mtime)) != SQLITE_OK) {
175 cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
176 return rc;
177 }
178 if ((rc = sqlite3_bind_int64(stmt, 6, type)) != SQLITE_OK) {
179 cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
180 return rc;
181 }
182 /* question: can we use SQLITE_STATIC instead? */
183 if ((rc = sqlite3_bind_text(stmt, 7, name, -1, SQLITE_TRANSIENT)) != SQLITE_OK) {
184 cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
185 return rc;
186 }
187 if ((rc = sqlite3_bind_blob(stmt, 8, value, size, SQLITE_TRANSIENT)) != SQLITE_OK) {
188 cfs_critical("sqlite3_bind failed: %s\n", sqlite3_errmsg(db));
189 return rc;
190 }
191
192 if ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
193 cfs_critical("sqlite3_step failed: %s\n", sqlite3_errmsg(db));
194 sqlite3_reset(stmt);
195 return rc;
196 }
197
198 sqlite3_reset(stmt);
199
200 return SQLITE_OK;
201 }
202
203 static int bdb_backend_delete_inode(
204 db_backend_t *bdb,
205 guint64 inode)
206 {
207 int rc;
208
209 cfs_debug("enter dbd_backend_delete_inode");
210
211 sqlite3_stmt *stmt = bdb->stmt_delete_entry;
212
213 if ((rc = sqlite3_bind_int64(stmt, 1, inode)) != SQLITE_OK) {
214 cfs_critical("delete_inode/sqlite3_bind failed: %s\n", sqlite3_errmsg(bdb->db));
215 return rc;
216 }
217
218 if ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
219 cfs_critical("delete_inode failed: %s\n", sqlite3_errmsg(bdb->db));
220 sqlite3_reset(stmt);
221 return rc;
222 }
223
224 sqlite3_reset(stmt);
225
226 return SQLITE_OK;
227 }
228
229 int bdb_backend_write(
230 db_backend_t *bdb,
231 guint64 inode,
232 guint64 parent,
233 guint64 version,
234 guint32 writer,
235 guint32 mtime,
236 guint32 size,
237 char type,
238 char *name,
239 gpointer value,
240 guint64 delete_inode)
241 {
242 g_return_val_if_fail(bdb != NULL, SQLITE_PERM);
243 g_return_val_if_fail(inode == 0 || (name != NULL && name[0]), SQLITE_PERM);
244 g_return_val_if_fail(type == DT_REG || type == DT_DIR, SQLITE_PERM);
245 int rc;
246
247 gboolean need_txn = (inode != 0 || delete_inode != 0);
248
249 if (need_txn) {
250 rc = sqlite3_step(bdb->stmt_begin);
251 sqlite3_reset(bdb->stmt_begin);
252 if (rc != SQLITE_DONE) {
253 cfs_critical("begin transaction failed: %s\n", sqlite3_errmsg(bdb->db));
254 return rc;
255 }
256 }
257
258 if (delete_inode != 0) {
259 if ((rc = bdb_backend_delete_inode(bdb, delete_inode)) != SQLITE_OK)
260 goto rollback;
261 }
262
263 if (inode != 0) {
264
265 sqlite3_stmt *stmt = (inode > version) ?
266 bdb->stmt_insert_entry : bdb->stmt_replace_entry;
267
268 rc = backend_write_inode(bdb->db, stmt, inode, parent, version,
269 writer, mtime, size, type, name, value);
270 if (rc != SQLITE_OK)
271 goto rollback;
272
273 if (sqlite3_changes(bdb->db) != 1) {
274 cfs_critical("no such inode %016zX", inode);
275 goto rollback;
276 }
277 }
278
279 rc = backend_write_inode(bdb->db, bdb->stmt_replace_entry, 0, 0, version,
280 writer, mtime, 0, DT_REG, VERSIONFILENAME, NULL);
281
282 if (rc != SQLITE_OK)
283 goto rollback;
284
285
286 if (need_txn) {
287 rc = sqlite3_step(bdb->stmt_commit);
288 sqlite3_reset(bdb->stmt_commit);
289 if (rc != SQLITE_DONE) {
290 cfs_critical("commit transaction failed: %s\n", sqlite3_errmsg(bdb->db));
291 goto rollback;
292 }
293 }
294
295 return SQLITE_OK;
296
297 rollback:
298
299 if (!need_txn)
300 return rc;
301
302 int rbrc = sqlite3_step(bdb->stmt_rollback);
303 sqlite3_reset(bdb->stmt_rollback);
304 if (rbrc != SQLITE_DONE) {
305 cfs_critical("rollback transaction failed: %s\n", sqlite3_errmsg(bdb->db));
306 return rc;
307 }
308
309 return rc;
310 }
311
312 static gboolean bdb_backend_load_index(
313 db_backend_t *bdb,
314 memdb_tree_entry_t *root,
315 GHashTable *index)
316 {
317 g_return_val_if_fail(bdb != NULL, FALSE);
318 g_return_val_if_fail(root != NULL, FALSE);
319 g_return_val_if_fail(index != NULL, FALSE);
320 g_return_val_if_fail(root->version == 0, FALSE);
321 g_return_val_if_fail(g_hash_table_size(index) == 1, FALSE);
322
323 int rc;
324
325 sqlite3_stmt *stmt = bdb->stmt_load_all;
326
327 while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
328
329 memdb_tree_entry_t *te;
330
331 guint64 inode = sqlite3_column_int64(stmt, 0);
332 const char *name = (const char *)sqlite3_column_text(stmt, 6);
333 int namelen = sqlite3_column_bytes(stmt, 6);
334 if (name == NULL || namelen == 0) {
335 cfs_critical("inode has no name (inode = %016zX)", inode);
336 goto fail;
337 }
338 te = g_malloc0(sizeof(memdb_tree_entry_t) + namelen + 1);
339 strcpy(te->name, name);
340
341 te->inode = inode;
342 te->parent = sqlite3_column_int64(stmt, 1);
343 te->version = sqlite3_column_int64(stmt, 2);
344 te->writer = sqlite3_column_int64(stmt, 3) & 0x0ffffffff;
345 te->mtime = sqlite3_column_int64(stmt, 4) & 0x0ffffffff;
346 te->type = sqlite3_column_int64(stmt, 5) & 255;
347
348 gconstpointer value = sqlite3_column_blob(stmt, 7);
349
350 int size = sqlite3_column_bytes(stmt, 7);
351 te->size = size;
352
353 if (te->type == DT_REG) {
354 if (size > 0)
355 te->data.value = g_memdup(value, size);
356 } else if (te->type == DT_DIR) {
357 if (size) {
358 cfs_critical("directory inode contains data (inode = %016zX)",
359 te->inode);
360 g_free(te);
361 goto fail;
362 }
363 te->data.entries = NULL;
364 } else {
365 cfs_critical("inode has unknown type (inode = %016zX, type = %d)",
366 te->inode, te->type);
367 g_free(te);
368 goto fail;
369 }
370
371 cfs_debug("name %s (inode = %016zX, parent = %016zX)",
372 te->name, te->inode, te->parent);
373
374 if (te->inode == 0) {
375 if (te->name && !strcmp(te->name, VERSIONFILENAME)) {
376 root->version = te->version;
377 root->writer = te->writer;
378 root->mtime = te->mtime;
379 memdb_tree_entry_free(te);
380 } else {
381 cfs_critical("root inode has unexpected name '%s'", te->name);
382 memdb_tree_entry_free(te);
383 goto fail;
384 }
385 } else {
386 memdb_tree_entry_t *pte;
387
388 if (!(pte = g_hash_table_lookup(index, &te->parent))) {
389
390 /* allocate placeholder (type == 0)
391 * this is simply replaced if we find a real inode later
392 */
393 pte = g_malloc0(sizeof(memdb_tree_entry_t));
394 pte->inode = te->parent;
395 pte->data.entries = g_hash_table_new(g_str_hash, g_str_equal);
396 g_hash_table_replace(index, &pte->inode, pte);
397
398 } else if (pte->type != DT_DIR) {
399 cfs_critical("parent is not a directory "
400 "(inode = %016zX, parent = %016zX, name = '%s')",
401 te->inode, te->parent, te->name);
402 memdb_tree_entry_free(te);
403 goto fail;
404 }
405
406 if (te->type == DT_DIR) {
407 te->data.entries = g_hash_table_new(g_str_hash, g_str_equal);
408 }
409
410 if (g_hash_table_lookup(pte->data.entries, te->name)) {
411 cfs_critical("found entry with duplicate name "
412 "(inode = %016zX, parent = %016zX, name = '%s')",
413 te->inode, te->parent, te->name);
414 goto fail;
415 }
416
417 g_hash_table_replace(pte->data.entries, te->name, te);
418 g_hash_table_replace(index, &te->inode, te);
419 }
420 }
421 if (rc != SQLITE_DONE) {
422 cfs_critical("select returned error: %s", sqlite3_errmsg(bdb->db));
423 goto fail;
424 }
425
426 /* no, check if all inodes have parents (there must be no placeholders) */
427 GHashTableIter iter;
428 gpointer key, value;
429 g_hash_table_iter_init (&iter, index);
430 while (g_hash_table_iter_next (&iter, &key, &value)) {
431 memdb_tree_entry_t *te = (memdb_tree_entry_t *)value;
432 if (te->type == 0) {
433 cfs_critical("missing directory inode (inode = %016zX)", te->inode);
434 goto fail;
435 }
436 }
437
438 sqlite3_reset(stmt);
439
440 return TRUE;
441
442 fail:
443 sqlite3_reset(stmt);
444
445 cfs_critical("DB load failed");
446
447 return FALSE;
448 }
449
450 gboolean bdb_backend_commit_update(
451 memdb_t *memdb,
452 memdb_index_t *master,
453 memdb_index_t *slave,
454 GList *inodes)
455 {
456 g_return_val_if_fail(memdb != NULL, FALSE);
457 g_return_val_if_fail(memdb->bdb != NULL, FALSE);
458 g_return_val_if_fail(master != NULL, FALSE);
459 g_return_val_if_fail(slave != NULL, FALSE);
460
461 cfs_debug("enter bdb_backend_commit_update");
462
463 memdb_tree_entry_t *root = NULL;
464 GHashTable *index = NULL;
465
466 db_backend_t *bdb = (db_backend_t *)memdb->bdb;
467 gboolean result = FALSE;
468
469 int rc;
470
471 rc = sqlite3_step(bdb->stmt_begin);
472 sqlite3_reset(bdb->stmt_begin);
473 if (rc != SQLITE_DONE) {
474 cfs_critical("begin transaction failed: %s\n", sqlite3_errmsg(bdb->db));
475 return rc;
476 }
477
478 g_mutex_lock (memdb->mutex);
479
480 /* first, delete anything not found in master index) */
481
482 int i = 0;
483 int j = 0;
484
485 for (i = 0; i < master->size; i++) {
486 guint64 inode = master->entries[i].inode;
487 guint64 slave_inode;
488 while (j < slave->size && (slave_inode = slave->entries[j].inode) <= inode) {
489
490 if (slave_inode < inode) {
491 if (bdb_backend_delete_inode(bdb, slave_inode) != SQLITE_OK)
492 goto abort;
493
494 cfs_debug("deleted inode %016zX", slave_inode);
495 }
496 j++;
497 }
498 if (j >= slave->size)
499 break;
500 }
501
502 while (j < slave->size) {
503 guint64 slave_inode = slave->entries[j].inode;
504
505 if (bdb_backend_delete_inode(bdb, slave_inode) != SQLITE_OK)
506 goto abort;
507
508 cfs_debug("deleted inode %016zX", slave_inode);
509
510 j++;
511 }
512
513 /* now add all updates */
514
515 GList *l = inodes;
516 while (l) {
517 memdb_tree_entry_t *te = (memdb_tree_entry_t *)l->data;
518
519 tree_entry_debug(te);
520
521 if (backend_write_inode(
522 bdb->db, bdb->stmt_replace_entry, te->inode, te->parent, te->version,
523 te->writer, te->mtime, te->size, te->type,
524 te->inode ? te->name : VERSIONFILENAME, te->data.value) != SQLITE_OK) {
525 goto abort;
526 }
527
528 l = g_list_next(l);
529 }
530
531 /* now try to reload */
532 root = memdb_tree_entry_new("");
533 root->data.entries = g_hash_table_new(g_str_hash, g_str_equal);
534 root->type = DT_DIR;
535
536 index = g_hash_table_new_full(g_int64_hash, g_int64_equal, NULL,
537 (GDestroyNotify)memdb_tree_entry_free);
538
539 g_hash_table_replace(index, &root->inode, root);
540
541 if (!bdb_backend_load_index(bdb, root, index))
542 goto abort;
543
544 if (!memdb->root->version) {
545 cfs_critical("new index has version 0 - internal error");
546 goto abort;
547 }
548
549 memdb_index_t *new_idx = memdb_encode_index(index, root);
550 if (!new_idx) {
551 cfs_critical("cant encode new index - internal error");
552 goto abort;
553 }
554
555 int idx_equal = (new_idx->bytes == master->bytes &&
556 (memcmp(master, new_idx, new_idx->bytes) == 0));
557
558 g_free (new_idx);
559
560 if (!idx_equal) {
561 cfs_critical("new index does not match master index - internal error");
562 goto abort;
563 }
564
565 rc = sqlite3_step(bdb->stmt_commit);
566 sqlite3_reset(bdb->stmt_commit);
567 if (rc != SQLITE_DONE) {
568 cfs_critical("commit transaction failed: %s\n", sqlite3_errmsg(bdb->db));
569 goto abort;
570 }
571
572 g_hash_table_destroy(memdb->index);
573 memdb->index = index;
574 memdb->root = root;
575 index = NULL;
576 root = NULL;
577
578 record_memdb_reload();
579
580 if (!memdb_recreate_vmlist(memdb)) {
581 cfs_critical("memdb_recreate_vmlist failed");
582 memdb->errors = 1;
583 result = FALSE;
584 goto ret;
585 }
586
587 memdb_update_locks(memdb);
588
589 result = TRUE;
590
591 ret:
592 g_mutex_unlock (memdb->mutex);
593
594 if (index)
595 g_hash_table_destroy(index);
596
597 cfs_debug("leave bdb_backend_commit_update (%d)", result);
598
599 return result;
600
601 abort:
602
603 memdb->errors = 1;
604
605 rc = sqlite3_step(bdb->stmt_rollback);
606 sqlite3_reset(bdb->stmt_rollback);
607 if (rc != SQLITE_DONE)
608 cfs_critical("rollback transaction failed: %s\n", sqlite3_errmsg(bdb->db));
609
610 result = FALSE;
611
612 goto ret;
613 }
614
615 void bdb_backend_close(db_backend_t *bdb)
616 {
617 g_return_if_fail(bdb != NULL);
618
619 sqlite3_finalize(bdb->stmt_insert_entry);
620 sqlite3_finalize(bdb->stmt_replace_entry);
621 sqlite3_finalize(bdb->stmt_update_entry);
622 sqlite3_finalize(bdb->stmt_delete_entry);
623 sqlite3_finalize(bdb->stmt_begin);
624 sqlite3_finalize(bdb->stmt_commit);
625 sqlite3_finalize(bdb->stmt_rollback);
626 sqlite3_finalize(bdb->stmt_load_all);
627
628 int rc;
629 if ((rc = sqlite3_close(bdb->db)) != SQLITE_OK) {
630 cfs_critical("sqlite3_close failed: %d\n", rc);
631 }
632
633 sqlite3_shutdown();
634
635 g_free(bdb);
636 }
637
638 db_backend_t *bdb_backend_open(
639 const char *filename,
640 memdb_tree_entry_t *root,
641 GHashTable *index)
642 {
643 g_return_val_if_fail(filename != NULL, NULL);
644 g_return_val_if_fail(root != NULL, NULL);
645 g_return_val_if_fail(index != NULL, NULL);
646
647 db_backend_t *bdb = g_new0(db_backend_t, 1);
648 g_return_val_if_fail(bdb != NULL, NULL);
649
650 int rc;
651
652 sqlite3_initialize();
653
654 if (!(bdb->db = bdb_create(filename)))
655 goto fail;
656
657 rc = sqlite3_prepare_v2(bdb->db, sql_insert_entry, -1, &bdb->stmt_insert_entry, NULL);
658 if (rc != SQLITE_OK) {
659 cfs_critical("sqlite3_prepare 'sql_insert_entry' failed: %s\n",
660 sqlite3_errmsg(bdb->db));
661 goto fail;
662 }
663 rc = sqlite3_prepare_v2(bdb->db, sql_update_entry, -1, &bdb->stmt_update_entry, NULL);
664 if (rc != SQLITE_OK) {
665 cfs_critical("sqlite3_prepare 'sql_update_entry' failed: %s\n",
666 sqlite3_errmsg(bdb->db));
667 goto fail;
668 }
669 rc = sqlite3_prepare_v2(bdb->db, sql_replace_entry, -1, &bdb->stmt_replace_entry, NULL);
670 if (rc != SQLITE_OK) {
671 cfs_critical("sqlite3_prepare 'sql_replace_entry' failed: %s\n",
672 sqlite3_errmsg(bdb->db));
673 goto fail;
674 }
675 rc = sqlite3_prepare_v2(bdb->db, sql_delete_entry, -1, &bdb->stmt_delete_entry, NULL);
676 if (rc != SQLITE_OK) {
677 cfs_critical("sqlite3_prepare 'sql_delete_entry' failed: %s\n",
678 sqlite3_errmsg(bdb->db));
679 goto fail;
680 }
681 rc = sqlite3_prepare_v2(bdb->db, sql_begin, -1, &bdb->stmt_begin, NULL);
682 if (rc != SQLITE_OK) {
683 cfs_critical("sqlite3_prepare 'sql_begin' failed: %s\n",
684 sqlite3_errmsg(bdb->db));
685 goto fail;
686 }
687 rc = sqlite3_prepare_v2(bdb->db, sql_commit, -1, &bdb->stmt_commit, NULL);
688 if (rc != SQLITE_OK) {
689 cfs_critical("sqlite3_prepare 'sql_commit' failed: %s\n",
690 sqlite3_errmsg(bdb->db));
691 goto fail;
692 }
693 rc = sqlite3_prepare_v2(bdb->db, sql_rollback, -1, &bdb->stmt_rollback, NULL);
694 if (rc != SQLITE_OK) {
695 cfs_critical("sqlite3_prepare 'sql_rollback' failed: %s\n",
696 sqlite3_errmsg(bdb->db));
697 goto fail;
698 }
699 rc = sqlite3_prepare_v2(bdb->db, sql_load_all, -1, &bdb->stmt_load_all, NULL);
700 if (rc != SQLITE_OK) {
701 cfs_critical("sqlite3_prepare 'sql_load_all' failed: %s\n",
702 sqlite3_errmsg(bdb->db));
703 goto fail;
704 }
705
706 if (!bdb_backend_load_index(bdb, root, index))
707 goto fail;
708
709 if (!root->version) {
710 root->version++;
711
712 guint32 mtime = time(NULL);
713
714 if (bdb_backend_write(bdb, 0, 0, root->version, 0, mtime,
715 0, DT_REG, NULL, NULL, 0) != SQLITE_OK)
716 goto fail;
717 }
718
719 return bdb;
720
721 fail:
722
723 bdb_backend_close(bdb);
724
725 return NULL;
726 }
727