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