xref: /titanic_52/usr/src/cmd/svc/configd/backend.c (revision 84ab085a13f931bc78e7415e7ce921dbaa14fcb3)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * sqlite is not compatible with _FILE_OFFSET_BITS=64, but we need to
31  * be able to statvfs(2) possibly large systems.  This define gives us
32  * access to the transitional interfaces.  See lfcompile64(5) for how
33  * _LARGEFILE64_SOURCE works.
34  */
35 #define	_LARGEFILE64_SOURCE
36 
37 #include <assert.h>
38 #include <door.h>
39 #include <dirent.h>
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <limits.h>
43 #include <pthread.h>
44 #include <stdarg.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <sys/stat.h>
49 #include <sys/statvfs.h>
50 #include <unistd.h>
51 #include <zone.h>
52 
53 #include "configd.h"
54 #include "repcache_protocol.h"
55 
56 #include "sqlite/sqlite.h"
57 #include "sqlite/sqlite-misc.h"
58 
59 /*
60  * This file has two purposes:
61  *
62  * 1. It contains the database schema, and the code for setting up our backend
63  *    databases, including installing said schema.
64  *
65  * 2. It provides a simplified interface to the SQL database library, and
66  *    synchronizes MT access to the database.
67  */
68 
69 typedef struct backend_spent {
70 	uint64_t bs_count;
71 	hrtime_t bs_time;
72 	hrtime_t bs_vtime;
73 } backend_spent_t;
74 
75 typedef struct backend_totals {
76 	backend_spent_t	bt_lock;	/* waiting for lock */
77 	backend_spent_t	bt_exec;	/* time spent executing SQL */
78 } backend_totals_t;
79 
80 typedef struct sqlite_backend {
81 	pthread_mutex_t	be_lock;
82 	pthread_t	be_thread;	/* thread holding lock */
83 	struct sqlite	*be_db;
84 	const char	*be_path;	/* path to db */
85 	int		be_readonly;	/* readonly at start, and still is */
86 	int		be_writing;	/* held for writing */
87 	backend_type_t	be_type;	/* type of db */
88 	hrtime_t	be_lastcheck;	/* time of last read-only check */
89 	backend_totals_t be_totals[2];	/* one for reading, one for writing */
90 } sqlite_backend_t;
91 
92 struct backend_tx {
93 	sqlite_backend_t	*bt_be;
94 	int			bt_readonly;
95 	int			bt_type;
96 	int			bt_full;	/* SQLITE_FULL during tx */
97 };
98 
99 #define	UPDATE_TOTALS_WR(sb, writing, field, ts, vts) { \
100 	backend_spent_t *__bsp = &(sb)->be_totals[!!(writing)].field; \
101 	__bsp->bs_count++;						\
102 	__bsp->bs_time += (gethrtime() - ts);				\
103 	__bsp->bs_vtime += (gethrvtime() - vts);			\
104 }
105 
106 #define	UPDATE_TOTALS(sb, field, ts, vts) \
107 	UPDATE_TOTALS_WR(sb, (sb)->be_writing, field, ts, vts)
108 
109 struct backend_query {
110 	char	*bq_buf;
111 	size_t	bq_size;
112 };
113 
114 struct backend_tbl_info {
115 	const char *bti_name;
116 	const char *bti_cols;
117 };
118 
119 struct backend_idx_info {
120 	const char *bxi_tbl;
121 	const char *bxi_idx;
122 	const char *bxi_cols;
123 };
124 
125 static pthread_mutex_t backend_panic_lock = PTHREAD_MUTEX_INITIALIZER;
126 static pthread_cond_t backend_panic_cv = PTHREAD_COND_INITIALIZER;
127 pthread_t backend_panic_thread = 0;
128 
129 int backend_do_trace = 0;		/* invoke tracing callback */
130 int backend_print_trace = 0;		/* tracing callback prints SQL */
131 int backend_panic_abort = 0;		/* abort when panicking */
132 
133 /* interval between read-only checks while starting up */
134 #define	BACKEND_READONLY_CHECK_INTERVAL	(2 * (hrtime_t)NANOSEC)
135 
136 /*
137  * Any change to the below schema should bump the version number
138  */
139 #define	BACKEND_SCHEMA_VERSION		5
140 
141 static struct backend_tbl_info tbls_normal[] = { /* BACKEND_TYPE_NORMAL */
142 	/*
143 	 * service_tbl holds all services.  svc_id is the identifier of the
144 	 * service.
145 	 */
146 	{
147 		"service_tbl",
148 		"svc_id          INTEGER PRIMARY KEY,"
149 		"svc_name        CHAR(256) NOT NULL"
150 	},
151 
152 	/*
153 	 * instance_tbl holds all of the instances.  The parent service id
154 	 * is instance_svc.
155 	 */
156 	{
157 		"instance_tbl",
158 		"instance_id     INTEGER PRIMARY KEY,"
159 		"instance_name   CHAR(256) NOT NULL,"
160 		"instance_svc    INTEGER NOT NULL"
161 	},
162 
163 	/*
164 	 * snapshot_lnk_tbl links (instance, snapshot name) with snapshots.
165 	 */
166 	{
167 		"snapshot_lnk_tbl",
168 		"lnk_id          INTEGER PRIMARY KEY,"
169 		"lnk_inst_id     INTEGER NOT NULL,"
170 		"lnk_snap_name   CHAR(256) NOT NULL,"
171 		"lnk_snap_id     INTEGER NOT NULL"
172 	},
173 
174 	/*
175 	 * snaplevel_tbl maps a snapshot id to a set of named, ordered
176 	 * snaplevels.
177 	 */
178 	{
179 		"snaplevel_tbl",
180 		"snap_id                 INTEGER NOT NULL,"
181 		"snap_level_num          INTEGER NOT NULL,"
182 		"snap_level_id           INTEGER NOT NULL,"
183 		"snap_level_service_id   INTEGER NOT NULL,"
184 		"snap_level_service      CHAR(256) NOT NULL,"
185 		"snap_level_instance_id  INTEGER NULL,"
186 		"snap_level_instance     CHAR(256) NULL"
187 	},
188 
189 	/*
190 	 * snaplevel_lnk_tbl links snaplevels to property groups.
191 	 * snaplvl_pg_* is identical to the original property group,
192 	 * and snaplvl_gen_id overrides the generation number.
193 	 * The service/instance ids are as in the snaplevel.
194 	 */
195 	{
196 		"snaplevel_lnk_tbl",
197 		"snaplvl_level_id INTEGER NOT NULL,"
198 		"snaplvl_pg_id    INTEGER NOT NULL,"
199 		"snaplvl_pg_name  CHAR(256) NOT NULL,"
200 		"snaplvl_pg_type  CHAR(256) NOT NULL,"
201 		"snaplvl_pg_flags INTEGER NOT NULL,"
202 		"snaplvl_gen_id   INTEGER NOT NULL"
203 	},
204 
205 	{ NULL, NULL }
206 };
207 
208 static struct backend_idx_info idxs_normal[] = { /* BACKEND_TYPE_NORMAL */
209 	{ "service_tbl",	"name",	"svc_name" },
210 	{ "instance_tbl",	"name",	"instance_svc, instance_name" },
211 	{ "snapshot_lnk_tbl",	"name",	"lnk_inst_id, lnk_snap_name" },
212 	{ "snapshot_lnk_tbl",	"snapid", "lnk_snap_id" },
213 	{ "snaplevel_tbl",	"id",	"snap_id" },
214 	{ "snaplevel_lnk_tbl",	"id",	"snaplvl_pg_id" },
215 	{ "snaplevel_lnk_tbl",	"level", "snaplvl_level_id" },
216 	{ NULL, NULL, NULL }
217 };
218 
219 static struct backend_tbl_info tbls_np[] = { /* BACKEND_TYPE_NONPERSIST */
220 	{ NULL, NULL }
221 };
222 
223 static struct backend_idx_info idxs_np[] = {	/* BACKEND_TYPE_NONPERSIST */
224 	{ NULL, NULL, NULL }
225 };
226 
227 static struct backend_tbl_info tbls_common[] = { /* all backend types */
228 	/*
229 	 * pg_tbl defines property groups.  They are associated with a single
230 	 * service or instance.  The pg_gen_id links them with the latest
231 	 * "edited" version of its properties.
232 	 */
233 	{
234 		"pg_tbl",
235 		"pg_id           INTEGER PRIMARY KEY,"
236 		"pg_parent_id    INTEGER NOT NULL,"
237 		"pg_name         CHAR(256) NOT NULL,"
238 		"pg_type         CHAR(256) NOT NULL,"
239 		"pg_flags        INTEGER NOT NULL,"
240 		"pg_gen_id       INTEGER NOT NULL"
241 	},
242 
243 	/*
244 	 * prop_lnk_tbl links a particular pg_id and gen_id to a set of
245 	 * (prop_name, prop_type, val_id) trios.
246 	 */
247 	{
248 		"prop_lnk_tbl",
249 		"lnk_prop_id     INTEGER PRIMARY KEY,"
250 		"lnk_pg_id       INTEGER NOT NULL,"
251 		"lnk_gen_id      INTEGER NOT NULL,"
252 		"lnk_prop_name   CHAR(256) NOT NULL,"
253 		"lnk_prop_type   CHAR(2) NOT NULL,"
254 		"lnk_val_id      INTEGER"
255 	},
256 
257 	/*
258 	 * value_tbl maps a value_id to a set of values.  For any given
259 	 * value_id, value_type is constant.
260 	 */
261 	{
262 		"value_tbl",
263 		"value_id        INTEGER NOT NULL,"
264 		"value_type      CHAR(1) NOT NULL,"
265 		"value_value     VARCHAR NOT NULL"
266 	},
267 
268 	/*
269 	 * id_tbl has one row per id space
270 	 */
271 	{
272 		"id_tbl",
273 		"id_name         STRING NOT NULL,"
274 		"id_next         INTEGER NOT NULL"
275 	},
276 
277 	/*
278 	 * schema_version has a single row, which contains
279 	 * BACKEND_SCHEMA_VERSION at the time of creation.
280 	 */
281 	{
282 		"schema_version",
283 		"schema_version  INTEGER"
284 	},
285 	{ NULL, NULL }
286 };
287 
288 static struct backend_idx_info idxs_common[] = { /* all backend types */
289 	{ "pg_tbl",		"parent", "pg_parent_id" },
290 	{ "pg_tbl",		"name",	"pg_parent_id, pg_name" },
291 	{ "pg_tbl",		"type",	"pg_parent_id, pg_type" },
292 	{ "prop_lnk_tbl",	"base",	"lnk_pg_id, lnk_gen_id" },
293 	{ "prop_lnk_tbl",	"val",	"lnk_val_id" },
294 	{ "value_tbl",		"id",	"value_id" },
295 	{ "id_tbl",		"id",	"id_name" },
296 	{ NULL, NULL, NULL }
297 };
298 
299 struct run_single_int_info {
300 	uint32_t	*rs_out;
301 	int		rs_result;
302 };
303 
304 /*ARGSUSED*/
305 static int
306 run_single_int_callback(void *arg, int columns, char **vals, char **names)
307 {
308 	struct run_single_int_info *info = arg;
309 	uint32_t val;
310 
311 	char *endptr = vals[0];
312 
313 	assert(info->rs_result != REP_PROTOCOL_SUCCESS);
314 	assert(columns == 1);
315 
316 	if (vals[0] == NULL)
317 		return (BACKEND_CALLBACK_CONTINUE);
318 
319 	errno = 0;
320 	val = strtoul(vals[0], &endptr, 10);
321 	if ((val == 0 && endptr == vals[0]) || *endptr != 0 || errno != 0)
322 		backend_panic("malformed integer \"%20s\"", vals[0]);
323 
324 	*info->rs_out = val;
325 	info->rs_result = REP_PROTOCOL_SUCCESS;
326 	return (BACKEND_CALLBACK_CONTINUE);
327 }
328 
329 /*ARGSUSED*/
330 int
331 backend_fail_if_seen(void *arg, int columns, char **vals, char **names)
332 {
333 	return (BACKEND_CALLBACK_ABORT);
334 }
335 
336 /*
337  * check to see if we can successfully start a transaction;  if not, the
338  * filesystem is mounted read-only.
339  */
340 static int
341 backend_is_readonly(struct sqlite *db, const char *path)
342 {
343 	int r;
344 	statvfs64_t stat;
345 
346 	if (statvfs64(path, &stat) == 0 && (stat.f_flag & ST_RDONLY))
347 		return (SQLITE_READONLY);
348 
349 	r = sqlite_exec(db,
350 	    "BEGIN TRANSACTION; "
351 	    "UPDATE schema_version SET schema_version = schema_version; ",
352 	    NULL, NULL, NULL);
353 	(void) sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
354 	return (r);
355 }
356 
357 /*
358  * Check to see if the administrator has removed the writable bits on the
359  * repository file.  If they have, we don't allow modifications.
360  *
361  * Since we normally run with PRIV_FILE_DAC_WRITE, we have to use a separate
362  * check.
363  */
364 static int
365 backend_check_perm(const char *path)
366 {
367 	struct stat64 stat;
368 
369 	if (access(path, W_OK) < 0)
370 		return (SQLITE_READONLY);
371 
372 	if (stat64(path, &stat) == 0 &&
373 	    !(stat.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
374 		return (SQLITE_READONLY);
375 
376 	return (SQLITE_OK);
377 }
378 
379 static void
380 backend_trace_sql(void *arg, const char *sql)
381 {
382 	sqlite_backend_t *be = arg;
383 
384 	if (backend_print_trace) {
385 		(void) fprintf(stderr, "%d: %s\n", be->be_type, sql);
386 	}
387 }
388 
389 static sqlite_backend_t be_info[BACKEND_TYPE_TOTAL];
390 static sqlite_backend_t *bes[BACKEND_TYPE_TOTAL];
391 
392 #define	BACKEND_PANIC_TIMEOUT	(50 * MILLISEC)
393 /*
394  * backend_panic() -- some kind of database problem or corruption has been hit.
395  * We attempt to quiesce the other database users -- all of the backend sql
396  * entry points will call backend_panic(NULL) if a panic is in progress, as
397  * will any attempt to start a transaction.
398  *
399  * We give threads holding a backend lock 50ms (BACKEND_PANIC_TIMEOUT) to
400  * either drop the lock or call backend_panic().  If they don't respond in
401  * time, we'll just exit anyway.
402  */
403 void
404 backend_panic(const char *format, ...)
405 {
406 	int i;
407 	va_list args;
408 	int failed = 0;
409 
410 	(void) pthread_mutex_lock(&backend_panic_lock);
411 	if (backend_panic_thread != 0) {
412 		(void) pthread_mutex_unlock(&backend_panic_lock);
413 		/*
414 		 * first, drop any backend locks we're holding, then
415 		 * sleep forever on the panic_cv.
416 		 */
417 		for (i = 0; i < BACKEND_TYPE_TOTAL; i++) {
418 			if (bes[i] != NULL &&
419 			    bes[i]->be_thread == pthread_self())
420 				(void) pthread_mutex_unlock(&bes[i]->be_lock);
421 		}
422 		(void) pthread_mutex_lock(&backend_panic_lock);
423 		for (;;)
424 			(void) pthread_cond_wait(&backend_panic_cv,
425 			    &backend_panic_lock);
426 	}
427 	backend_panic_thread = pthread_self();
428 	(void) pthread_mutex_unlock(&backend_panic_lock);
429 
430 	for (i = 0; i < BACKEND_TYPE_TOTAL; i++) {
431 		if (bes[i] != NULL && bes[i]->be_thread == pthread_self())
432 			(void) pthread_mutex_unlock(&bes[i]->be_lock);
433 	}
434 
435 	va_start(args, format);
436 	configd_vcritical(format, args);
437 	va_end(args);
438 
439 	for (i = 0; i < BACKEND_TYPE_TOTAL; i++) {
440 		timespec_t rel;
441 
442 		rel.tv_sec = 0;
443 		rel.tv_nsec = BACKEND_PANIC_TIMEOUT;
444 
445 		if (bes[i] != NULL && bes[i]->be_thread != pthread_self()) {
446 			if (pthread_mutex_reltimedlock_np(&bes[i]->be_lock,
447 			    &rel) != 0)
448 				failed++;
449 		}
450 	}
451 	if (failed) {
452 		configd_critical("unable to quiesce database\n");
453 	}
454 
455 	if (backend_panic_abort)
456 		abort();
457 
458 	exit(CONFIGD_EXIT_DATABASE_BAD);
459 }
460 
461 /*
462  * Returns
463  *   _SUCCESS
464  *   _DONE - callback aborted query
465  *   _NO_RESOURCES - out of memory (_FULL & _TOOBIG?)
466  */
467 static int
468 backend_error(sqlite_backend_t *be, int error, char *errmsg)
469 {
470 	if (error == SQLITE_OK)
471 		return (REP_PROTOCOL_SUCCESS);
472 
473 	switch (error) {
474 	case SQLITE_ABORT:
475 		free(errmsg);
476 		return (REP_PROTOCOL_DONE);
477 
478 	case SQLITE_NOMEM:
479 	case SQLITE_FULL:
480 	case SQLITE_TOOBIG:
481 		free(errmsg);
482 		return (REP_PROTOCOL_FAIL_NO_RESOURCES);
483 
484 	default:
485 		backend_panic("%s: db error: %s", be->be_path, errmsg);
486 		/*NOTREACHED*/
487 	}
488 }
489 
490 static void
491 backend_backup_cleanup(const char **out_arg, ssize_t out_sz)
492 {
493 	char **out = (char **)out_arg;
494 
495 	while (out_sz-- > 0)
496 		free(*out++);
497 	free(out_arg);
498 }
499 
500 /*
501  * builds a inverse-time-sorted array of backup files.  The path is a
502  * a single buffer, and the pointers look like:
503  *
504  *	/this/is/a/full/path/to/repository-name-YYYYMMDDHHMMSS
505  *	^pathname		^	       ^(pathname+pathlen)
506  *				basename
507  *
508  * dirname will either be pathname, or ".".
509  *
510  * Returns the number of elements in the array, 0 if there are no previous
511  * backups, or -1 on error.
512  */
513 static ssize_t
514 backend_backup_get_prev(char *pathname, size_t pathlen, const char ***out_arg)
515 {
516 	char b_start, b_end;
517 	DIR *dir;
518 	char **out = NULL;
519 	char *name, *p;
520 	char *dirname, *basename;
521 	char *pathend;
522 	struct dirent *ent;
523 
524 	size_t count = 0;
525 	size_t baselen;
526 
527 	/*
528 	 * year, month, day, hour, min, sec, plus an '_'.
529 	 */
530 	const size_t ndigits = 4 + 5*2 + 1;
531 	const size_t baroffset = 4 + 2*2;
532 
533 	size_t idx;
534 
535 	pathend = pathname + pathlen;
536 	b_end = *pathend;
537 	*pathend = '\0';
538 
539 	basename = strrchr(pathname, '/');
540 
541 	if (basename != NULL) {
542 		assert(pathend > pathname && basename < pathend);
543 		basename++;
544 		dirname = pathname;
545 	} else {
546 		basename = pathname;
547 		dirname = ".";
548 	}
549 
550 	baselen = strlen(basename);
551 
552 	/*
553 	 * munge the string temporarily for the opendir(), then restore it.
554 	 */
555 	b_start = basename[0];
556 
557 	basename[0] = '\0';
558 	dir = opendir(dirname);
559 	basename[0] = b_start;		/* restore path */
560 
561 	if (dir == NULL)
562 		goto fail;
563 
564 
565 	while ((ent = readdir(dir)) != NULL) {
566 		/*
567 		 * Must match:
568 		 *	basename-YYYYMMDD_HHMMSS
569 		 * or we ignore it.
570 		 */
571 		if (strncmp(ent->d_name, basename, baselen) != 0)
572 			continue;
573 
574 		name = ent->d_name;
575 		if (name[baselen] != '-')
576 			continue;
577 
578 		p = name + baselen + 1;
579 
580 		for (idx = 0; idx < ndigits; idx++) {
581 			char c = p[idx];
582 			if (idx == baroffset && c != '_')
583 				break;
584 			if (idx != baroffset && (c < '0' || c > '9'))
585 				break;
586 		}
587 		if (idx != ndigits || p[idx] != '\0')
588 			continue;
589 
590 		/*
591 		 * We have a match.  insertion-sort it into our list.
592 		 */
593 		name = strdup(name);
594 		if (name == NULL)
595 			goto fail_closedir;
596 		p = strrchr(name, '-');
597 
598 		for (idx = 0; idx < count; idx++) {
599 			char *tmp = out[idx];
600 			char *tp = strrchr(tmp, '-');
601 
602 			int cmp = strcmp(p, tp);
603 			if (cmp == 0)
604 				cmp = strcmp(name, tmp);
605 
606 			if (cmp == 0) {
607 				free(name);
608 				name = NULL;
609 				break;
610 			} else if (cmp > 0) {
611 				out[idx] = name;
612 				name = tmp;
613 				p = tp;
614 			}
615 		}
616 
617 		if (idx == count) {
618 			char **new_out = realloc(out,
619 			    (count + 1) * sizeof (*out));
620 
621 			if (new_out == NULL) {
622 				free(name);
623 				goto fail_closedir;
624 			}
625 
626 			out = new_out;
627 			out[count++] = name;
628 		} else {
629 			assert(name == NULL);
630 		}
631 	}
632 	(void) closedir(dir);
633 
634 	basename[baselen] = b_end;
635 
636 	*out_arg = (const char **)out;
637 	return (count);
638 
639 fail_closedir:
640 	(void) closedir(dir);
641 fail:
642 	basename[0] = b_start;
643 	*pathend = b_end;
644 
645 	backend_backup_cleanup((const char **)out, count);
646 
647 	*out_arg = NULL;
648 	return (-1);
649 }
650 
651 /*
652  * Copies the repository path into out, a buffer of out_len bytes,
653  * removes the ".db" (or whatever) extension, and, if name is non-NULL,
654  * appends "-name" to it.  If name is non-NULL, it can fail with:
655  *
656  *	_TRUNCATED	will not fit in buffer.
657  *	_BAD_REQUEST	name is not a valid identifier
658  */
659 static rep_protocol_responseid_t
660 backend_backup_base(sqlite_backend_t *be, const char *name,
661     char *out, size_t out_len)
662 {
663 	char *p, *q;
664 	size_t len;
665 
666 	/*
667 	 * for paths of the form /path/to/foo.db, we truncate at the final
668 	 * '.'.
669 	 */
670 	(void) strlcpy(out, be->be_path, out_len);
671 
672 	p = strrchr(out, '/');
673 	q = strrchr(out, '.');
674 
675 	if (p != NULL && q != NULL && q > p)
676 		*q = 0;
677 
678 	if (name != NULL) {
679 		len = strlen(out);
680 		assert(len < out_len);
681 
682 		out += len;
683 		out_len -= len;
684 
685 		len = strlen(name);
686 
687 		/*
688 		 * verify that the name tag is entirely alphabetic,
689 		 * non-empty, and not too long.
690 		 */
691 		if (len == 0 || len >= REP_PROTOCOL_NAME_LEN ||
692 		    uu_check_name(name, UU_NAME_DOMAIN) < 0)
693 			return (REP_PROTOCOL_FAIL_BAD_REQUEST);
694 
695 		if (snprintf(out, out_len, "-%s", name) >= out_len)
696 			return (REP_PROTOCOL_FAIL_TRUNCATED);
697 	}
698 
699 	return (REP_PROTOCOL_SUCCESS);
700 }
701 
702 /*
703  * See if a backup is needed.  We do a backup unless both files are
704  * byte-for-byte identical.
705  */
706 static int
707 backend_check_backup_needed(const char *rep_name, const char *backup_name)
708 {
709 	int repfd = open(rep_name, O_RDONLY);
710 	int fd = open(backup_name, O_RDONLY);
711 	struct stat s_rep, s_backup;
712 	int c1, c2;
713 
714 	FILE *f_rep = NULL;
715 	FILE *f_backup = NULL;
716 
717 	if (repfd < 0 || fd < 0)
718 		goto fail;
719 
720 	if (fstat(repfd, &s_rep) < 0 || fstat(fd, &s_backup) < 0)
721 		goto fail;
722 
723 	/*
724 	 * if they are the same file, we need to do a backup to break the
725 	 * hard link or symlink involved.
726 	 */
727 	if (s_rep.st_ino == s_backup.st_ino && s_rep.st_dev == s_backup.st_dev)
728 		goto fail;
729 
730 	if (s_rep.st_size != s_backup.st_size)
731 		goto fail;
732 
733 	if ((f_rep = fdopen(repfd, "r")) == NULL ||
734 	    (f_backup = fdopen(fd, "r")) == NULL)
735 		goto fail;
736 
737 	do {
738 		c1 = getc(f_rep);
739 		c2 = getc(f_backup);
740 		if (c1 != c2)
741 			goto fail;
742 	} while (c1 != EOF);
743 
744 	if (!ferror(f_rep) && !ferror(f_backup)) {
745 		(void) fclose(f_rep);
746 		(void) fclose(f_backup);
747 		(void) close(repfd);
748 		(void) close(fd);
749 		return (0);
750 	}
751 
752 fail:
753 	if (f_rep != NULL)
754 		(void) fclose(f_rep);
755 	if (f_backup != NULL)
756 		(void) fclose(f_backup);
757 	if (repfd >= 0)
758 		(void) close(repfd);
759 	if (fd >= 0)
760 		(void) close(fd);
761 	return (1);
762 }
763 
764 /*
765  * Can return:
766  *	_BAD_REQUEST		name is not valid
767  *	_TRUNCATED		name is too long for current repository path
768  *	_UNKNOWN		failed for unknown reason (details written to
769  *				console)
770  *	_BACKEND_READONLY	backend is not writable
771  *
772  *	_SUCCESS		Backup completed successfully.
773  */
774 static rep_protocol_responseid_t
775 backend_create_backup_locked(sqlite_backend_t *be, const char *name)
776 {
777 	const char **old_list;
778 	ssize_t old_sz;
779 	ssize_t old_max = max_repository_backups;
780 	ssize_t cur;
781 
782 	char *finalname;
783 
784 	char finalpath[PATH_MAX];
785 	char tmppath[PATH_MAX];
786 	char buf[8192];
787 	int infd, outfd;
788 	size_t len;
789 	off_t inlen, outlen, offset;
790 
791 	time_t now;
792 	struct tm now_tm;
793 
794 	rep_protocol_responseid_t result;
795 
796 	if (be->be_readonly)
797 		return (REP_PROTOCOL_FAIL_BACKEND_READONLY);
798 
799 	result = backend_backup_base(be, name, finalpath, sizeof (finalpath));
800 	if (result != REP_PROTOCOL_SUCCESS)
801 		return (result);
802 
803 	if (!backend_check_backup_needed(be->be_path, finalpath)) {
804 		return (REP_PROTOCOL_SUCCESS);
805 	}
806 
807 	/*
808 	 * remember the original length, and the basename location
809 	 */
810 	len = strlen(finalpath);
811 	finalname = strrchr(finalpath, '/');
812 	if (finalname != NULL)
813 		finalname++;
814 	else
815 		finalname = finalpath;
816 
817 	(void) strlcpy(tmppath, finalpath, sizeof (tmppath));
818 	if (strlcat(tmppath, "-tmpXXXXXX", sizeof (tmppath)) >=
819 	    sizeof (tmppath))
820 		return (REP_PROTOCOL_FAIL_TRUNCATED);
821 
822 	now = time(NULL);
823 	if (localtime_r(&now, &now_tm) == NULL) {
824 		configd_critical(
825 		    "\"%s\" backup failed: localtime(3C) failed: %s\n", name,
826 		    be->be_path, strerror(errno));
827 		return (REP_PROTOCOL_FAIL_UNKNOWN);
828 	}
829 
830 	if (strftime(finalpath + len, sizeof (finalpath) - len,
831 	    "-%Y""%m""%d""_""%H""%M""%S", &now_tm) >=
832 	    sizeof (finalpath) - len) {
833 		return (REP_PROTOCOL_FAIL_TRUNCATED);
834 	}
835 
836 	infd = open(be->be_path, O_RDONLY);
837 	if (infd < 0) {
838 		configd_critical("\"%s\" backup failed: opening %s: %s\n", name,
839 		    be->be_path, strerror(errno));
840 		return (REP_PROTOCOL_FAIL_UNKNOWN);
841 	}
842 
843 	outfd = mkstemp(tmppath);
844 	if (outfd < 0) {
845 		configd_critical("\"%s\" backup failed: mkstemp(%s): %s\n",
846 		    name, tmppath, strerror(errno));
847 		(void) close(infd);
848 		return (REP_PROTOCOL_FAIL_UNKNOWN);
849 	}
850 
851 	for (;;) {
852 		do {
853 			inlen = read(infd, buf, sizeof (buf));
854 		} while (inlen < 0 && errno == EINTR);
855 
856 		if (inlen <= 0)
857 			break;
858 
859 		for (offset = 0; offset < inlen; offset += outlen) {
860 			do {
861 				outlen = write(outfd, buf + offset,
862 				    inlen - offset);
863 			} while (outlen < 0 && errno == EINTR);
864 
865 			if (outlen >= 0)
866 				continue;
867 
868 			configd_critical(
869 			    "\"%s\" backup failed: write to %s: %s\n",
870 			    name, tmppath, strerror(errno));
871 			result = REP_PROTOCOL_FAIL_UNKNOWN;
872 			goto fail;
873 		}
874 	}
875 
876 	if (inlen < 0) {
877 		configd_critical(
878 		    "\"%s\" backup failed: read from %s: %s\n",
879 		    name, be->be_path, strerror(errno));
880 		goto fail;
881 	}
882 
883 	/*
884 	 * grab the old list before doing our re-name.
885 	 */
886 	if (old_max > 0)
887 		old_sz = backend_backup_get_prev(finalpath, len, &old_list);
888 
889 	if (rename(tmppath, finalpath) < 0) {
890 		configd_critical(
891 		    "\"%s\" backup failed: rename(%s, %s): %s\n",
892 		    name, tmppath, finalpath, strerror(errno));
893 		result = REP_PROTOCOL_FAIL_UNKNOWN;
894 		goto fail;
895 	}
896 
897 	tmppath[len] = 0;	/* strip -XXXXXX, for reference symlink */
898 
899 	(void) unlink(tmppath);
900 	if (symlink(finalname, tmppath) < 0) {
901 		configd_critical(
902 		    "\"%s\" backup completed, but updating "
903 		    "\"%s\" symlink to \"%s\" failed: %s\n",
904 		    name, tmppath, finalname, strerror(errno));
905 	}
906 
907 	if (old_max > 0 && old_sz > 0) {
908 		/* unlink all but the first (old_max - 1) files */
909 		for (cur = old_max - 1; cur < old_sz; cur++) {
910 			(void) strlcpy(finalname, old_list[cur],
911 			    sizeof (finalpath) - (finalname - finalpath));
912 			if (unlink(finalpath) < 0)
913 				configd_critical(
914 				    "\"%s\" backup completed, but removing old "
915 				    "file \"%s\" failed: %s\n",
916 				    name, finalpath, strerror(errno));
917 		}
918 
919 		backend_backup_cleanup(old_list, old_sz);
920 	}
921 
922 	result = REP_PROTOCOL_SUCCESS;
923 
924 fail:
925 	(void) close(infd);
926 	(void) close(outfd);
927 	if (result != REP_PROTOCOL_SUCCESS)
928 		(void) unlink(tmppath);
929 
930 	return (result);
931 }
932 
933 static int
934 backend_check_readonly(sqlite_backend_t *be, int writing, hrtime_t t)
935 {
936 	char *errp;
937 	struct sqlite *new;
938 	int r;
939 
940 	assert(be->be_readonly);
941 	assert(be == bes[BACKEND_TYPE_NORMAL]);
942 
943 	/*
944 	 * If we don't *need* to be writable, only check every once in a
945 	 * while.
946 	 */
947 	if (!writing) {
948 		if ((uint64_t)(t - be->be_lastcheck) <
949 		    BACKEND_READONLY_CHECK_INTERVAL)
950 			return (REP_PROTOCOL_SUCCESS);
951 		be->be_lastcheck = t;
952 	}
953 
954 	new = sqlite_open(be->be_path, 0600, &errp);
955 	if (new == NULL) {
956 		backend_panic("reopening %s: %s\n", be->be_path, errp);
957 		/*NOTREACHED*/
958 	}
959 	r = backend_is_readonly(new, be->be_path);
960 
961 	if (r != SQLITE_OK) {
962 		sqlite_close(new);
963 		if (writing)
964 			return (REP_PROTOCOL_FAIL_BACKEND_READONLY);
965 		return (REP_PROTOCOL_SUCCESS);
966 	}
967 
968 	/*
969 	 * We can write!  Swap the db handles, mark ourself writable,
970 	 * and make a backup.
971 	 */
972 	sqlite_close(be->be_db);
973 	be->be_db = new;
974 	be->be_readonly = 0;
975 
976 	if (backend_create_backup_locked(be, REPOSITORY_BOOT_BACKUP) !=
977 	    REP_PROTOCOL_SUCCESS) {
978 		configd_critical(
979 		    "unable to create \"%s\" backup of \"%s\"\n",
980 		    REPOSITORY_BOOT_BACKUP, be->be_path);
981 	}
982 
983 	return (REP_PROTOCOL_SUCCESS);
984 }
985 
986 /*
987  * If t is not BACKEND_TYPE_NORMAL, can fail with
988  *   _BACKEND_ACCESS - backend does not exist
989  *
990  * If writing is nonzero, can also fail with
991  *   _BACKEND_READONLY - backend is read-only
992  */
993 static int
994 backend_lock(backend_type_t t, int writing, sqlite_backend_t **bep)
995 {
996 	sqlite_backend_t *be = NULL;
997 	hrtime_t ts, vts;
998 
999 	*bep = NULL;
1000 
1001 	assert(t == BACKEND_TYPE_NORMAL ||
1002 	    t == BACKEND_TYPE_NONPERSIST);
1003 
1004 	be = bes[t];
1005 	if (t == BACKEND_TYPE_NORMAL)
1006 		assert(be != NULL);		/* should always be there */
1007 
1008 	if (be == NULL)
1009 		return (REP_PROTOCOL_FAIL_BACKEND_ACCESS);
1010 
1011 	if (backend_panic_thread != 0)
1012 		backend_panic(NULL);		/* don't proceed */
1013 
1014 	ts = gethrtime();
1015 	vts = gethrvtime();
1016 	(void) pthread_mutex_lock(&be->be_lock);
1017 	UPDATE_TOTALS_WR(be, writing, bt_lock, ts, vts);
1018 
1019 	if (backend_panic_thread != 0) {
1020 		(void) pthread_mutex_unlock(&be->be_lock);
1021 		backend_panic(NULL);		/* don't proceed */
1022 	}
1023 	be->be_thread = pthread_self();
1024 
1025 	if (be->be_readonly) {
1026 		int r;
1027 		assert(t == BACKEND_TYPE_NORMAL);
1028 
1029 		r = backend_check_readonly(be, writing, ts);
1030 		if (r != REP_PROTOCOL_SUCCESS) {
1031 			be->be_thread = 0;
1032 			(void) pthread_mutex_unlock(&be->be_lock);
1033 			return (r);
1034 		}
1035 	}
1036 
1037 	if (writing && t == BACKEND_TYPE_NORMAL &&
1038 	    backend_check_perm(be->be_path) != SQLITE_OK) {
1039 		be->be_thread = 0;
1040 		(void) pthread_mutex_unlock(&be->be_lock);
1041 		return (REP_PROTOCOL_FAIL_BACKEND_READONLY);
1042 	}
1043 
1044 	if (backend_do_trace)
1045 		(void) sqlite_trace(be->be_db, backend_trace_sql, be);
1046 	else
1047 		(void) sqlite_trace(be->be_db, NULL, NULL);
1048 
1049 	be->be_writing = writing;
1050 	*bep = be;
1051 	return (REP_PROTOCOL_SUCCESS);
1052 }
1053 
1054 static void
1055 backend_unlock(sqlite_backend_t *be)
1056 {
1057 	be->be_writing = 0;
1058 	be->be_thread = 0;
1059 	(void) pthread_mutex_unlock(&be->be_lock);
1060 }
1061 
1062 static void
1063 backend_destroy(sqlite_backend_t *be)
1064 {
1065 	if (be->be_db != NULL) {
1066 		sqlite_close(be->be_db);
1067 		be->be_db = NULL;
1068 	}
1069 	be->be_thread = 0;
1070 	(void) pthread_mutex_unlock(&be->be_lock);
1071 	(void) pthread_mutex_destroy(&be->be_lock);
1072 }
1073 
1074 static void
1075 backend_create_finish(backend_type_t backend_id, sqlite_backend_t *be)
1076 {
1077 	assert(MUTEX_HELD(&be->be_lock));
1078 	assert(be == &be_info[backend_id]);
1079 
1080 	bes[backend_id] = be;
1081 	(void) pthread_mutex_unlock(&be->be_lock);
1082 }
1083 
1084 static int
1085 backend_fd_write(int fd, const char *mess)
1086 {
1087 	int len = strlen(mess);
1088 	int written;
1089 
1090 	while (len > 0) {
1091 		if ((written = write(fd, mess, len)) < 0)
1092 			return (-1);
1093 		mess += written;
1094 		len -= written;
1095 	}
1096 	return (0);
1097 }
1098 
1099 /*
1100  * Can return:
1101  *	_BAD_REQUEST		name is not valid
1102  *	_TRUNCATED		name is too long for current repository path
1103  *	_UNKNOWN		failed for unknown reason (details written to
1104  *				console)
1105  *	_BACKEND_READONLY	backend is not writable
1106  *
1107  *	_SUCCESS		Backup completed successfully.
1108  */
1109 rep_protocol_responseid_t
1110 backend_create_backup(const char *name)
1111 {
1112 	rep_protocol_responseid_t result;
1113 	sqlite_backend_t *be;
1114 
1115 	result = backend_lock(BACKEND_TYPE_NORMAL, 0, &be);
1116 	if (result != REP_PROTOCOL_SUCCESS)
1117 		return (result);
1118 
1119 	result = backend_create_backup_locked(be, name);
1120 	backend_unlock(be);
1121 
1122 	return (result);
1123 }
1124 
1125 /*ARGSUSED*/
1126 static int
1127 backend_integrity_callback(void *private, int narg, char **vals, char **cols)
1128 {
1129 	char **out = private;
1130 	char *old = *out;
1131 	char *new;
1132 	const char *info;
1133 	size_t len;
1134 	int x;
1135 
1136 	for (x = 0; x < narg; x++) {
1137 		if ((info = vals[x]) != NULL &&
1138 		    strcmp(info, "ok") != 0) {
1139 			len = (old == NULL)? 0 : strlen(old);
1140 			len += strlen(info) + 2;	/* '\n' + '\0' */
1141 
1142 			new = realloc(old, len);
1143 			if (new == NULL)
1144 				return (BACKEND_CALLBACK_ABORT);
1145 			if (old == NULL)
1146 				new[0] = 0;
1147 			old = *out = new;
1148 			(void) strlcat(new, info, len);
1149 			(void) strlcat(new, "\n", len);
1150 		}
1151 	}
1152 	return (BACKEND_CALLBACK_CONTINUE);
1153 }
1154 
1155 #define	BACKEND_CREATE_LOCKED		-2
1156 #define	BACKEND_CREATE_FAIL		-1
1157 #define	BACKEND_CREATE_SUCCESS		0
1158 #define	BACKEND_CREATE_READONLY		1
1159 #define	BACKEND_CREATE_NEED_INIT	2
1160 static int
1161 backend_create(backend_type_t backend_id, const char *db_file,
1162     sqlite_backend_t **bep)
1163 {
1164 	char *errp;
1165 	char *integrity_results = NULL;
1166 	sqlite_backend_t *be;
1167 	int r;
1168 	uint32_t val = -1UL;
1169 	struct run_single_int_info info;
1170 	int fd;
1171 
1172 	assert(backend_id >= 0 && backend_id < BACKEND_TYPE_TOTAL);
1173 
1174 	be = &be_info[backend_id];
1175 	assert(be->be_db == NULL);
1176 
1177 	(void) pthread_mutex_init(&be->be_lock, NULL);
1178 	(void) pthread_mutex_lock(&be->be_lock);
1179 
1180 	be->be_type = backend_id;
1181 	be->be_path = strdup(db_file);
1182 	if (be->be_path == NULL) {
1183 		perror("malloc");
1184 		goto fail;
1185 	}
1186 
1187 	be->be_db = sqlite_open(be->be_path, 0600, &errp);
1188 
1189 	if (be->be_db == NULL) {
1190 		if (strstr(errp, "out of memory") != NULL) {
1191 			configd_critical("%s: %s\n", db_file, errp);
1192 			free(errp);
1193 
1194 			goto fail;
1195 		}
1196 
1197 		/* report it as an integrity failure */
1198 		integrity_results = errp;
1199 		errp = NULL;
1200 		goto integrity_fail;
1201 	}
1202 
1203 	/*
1204 	 * check if we are inited and of the correct schema version
1205 	 *
1206 	 * Eventually, we'll support schema upgrade here.
1207 	 */
1208 	info.rs_out = &val;
1209 	info.rs_result = REP_PROTOCOL_FAIL_NOT_FOUND;
1210 
1211 	r = sqlite_exec(be->be_db, "SELECT schema_version FROM schema_version;",
1212 	    run_single_int_callback, &info, &errp);
1213 	if (r == SQLITE_ERROR &&
1214 	    strcmp("no such table: schema_version", errp) == 0) {
1215 		free(errp);
1216 		/*
1217 		 * Could be an empty repository, could be pre-schema_version
1218 		 * schema.  Check for id_tbl, which has always been there.
1219 		 */
1220 		r = sqlite_exec(be->be_db, "SELECT count() FROM id_tbl;",
1221 		    NULL, NULL, &errp);
1222 		if (r == SQLITE_ERROR &&
1223 		    strcmp("no such table: id_tbl", errp) == 0) {
1224 			free(errp);
1225 			*bep = be;
1226 			return (BACKEND_CREATE_NEED_INIT);
1227 		}
1228 
1229 		configd_critical("%s: schema version mismatch\n", db_file);
1230 		goto fail;
1231 	}
1232 	if (r == SQLITE_BUSY || r == SQLITE_LOCKED) {
1233 		free(errp);
1234 		*bep = NULL;
1235 		backend_destroy(be);
1236 		return (BACKEND_CREATE_LOCKED);
1237 	}
1238 	if (r == SQLITE_OK) {
1239 		if (info.rs_result == REP_PROTOCOL_FAIL_NOT_FOUND ||
1240 		    val != BACKEND_SCHEMA_VERSION) {
1241 			configd_critical("%s: schema version mismatch\n",
1242 			    db_file);
1243 			goto fail;
1244 		}
1245 	}
1246 
1247 	/*
1248 	 * pull in the whole database sequentially.
1249 	 */
1250 	if ((fd = open(db_file, O_RDONLY)) >= 0) {
1251 		size_t sz = 64 * 1024;
1252 		char *buffer = malloc(sz);
1253 		if (buffer != NULL) {
1254 			while (read(fd, buffer, sz) > 0)
1255 				;
1256 			free(buffer);
1257 		}
1258 		(void) close(fd);
1259 	}
1260 
1261 	/*
1262 	 * run an integrity check
1263 	 */
1264 	r = sqlite_exec(be->be_db, "PRAGMA integrity_check;",
1265 	    backend_integrity_callback, &integrity_results, &errp);
1266 
1267 	if (r == SQLITE_BUSY || r == SQLITE_LOCKED) {
1268 		free(errp);
1269 		*bep = NULL;
1270 		backend_destroy(be);
1271 		return (BACKEND_CREATE_LOCKED);
1272 	}
1273 	if (r == SQLITE_ABORT) {
1274 		free(errp);
1275 		errp = NULL;
1276 		integrity_results = "out of memory running integrity check\n";
1277 	} else if (r != SQLITE_OK && integrity_results == NULL) {
1278 		integrity_results = errp;
1279 		errp = NULL;
1280 	}
1281 
1282 integrity_fail:
1283 	if (integrity_results != NULL) {
1284 		const char *fname = "/etc/svc/volatile/db_errors";
1285 		if ((fd = open(fname, O_CREAT|O_WRONLY|O_APPEND, 0600)) < 0) {
1286 			fname = NULL;
1287 		} else {
1288 			if (backend_fd_write(fd, "\n\n") < 0 ||
1289 			    backend_fd_write(fd, db_file) < 0 ||
1290 			    backend_fd_write(fd,
1291 			    ": PRAGMA integrity_check; failed.  Results:\n") <
1292 			    0 || backend_fd_write(fd, integrity_results) < 0 ||
1293 			    backend_fd_write(fd, "\n\n") < 0) {
1294 				fname = NULL;
1295 			}
1296 			(void) close(fd);
1297 		}
1298 
1299 		if (!is_main_repository ||
1300 		    backend_id == BACKEND_TYPE_NONPERSIST) {
1301 			if (fname != NULL)
1302 				configd_critical(
1303 				    "%s: integrity check failed. Details in "
1304 				    "%s\n", db_file, fname);
1305 			else
1306 				configd_critical(
1307 				    "%s: integrity check failed: %s\n",
1308 				    db_file);
1309 		} else {
1310 			(void) fprintf(stderr,
1311 "\n"
1312 "svc.configd: smf(5) database integrity check of:\n"
1313 "\n"
1314 "    %s\n"
1315 "\n"
1316 "  failed. The database might be damaged or a media error might have\n"
1317 "  prevented it from being verified.  Additional information useful to\n"
1318 "  your service provider%s%s\n"
1319 "\n"
1320 "  The system will not be able to boot until you have restored a working\n"
1321 "  database.  svc.startd(1M) will provide a sulogin(1M) prompt for recovery\n"
1322 "  purposes.  The command:\n"
1323 "\n"
1324 "    /lib/svc/bin/restore_repository\n"
1325 "\n"
1326 "  can be run to restore a backup version of your repository.  See\n"
1327 "  http://sun.com/msg/SMF-8000-MY for more information.\n"
1328 "\n",
1329 			db_file,
1330 			(fname == NULL)? ":\n\n" : " is in:\n\n    ",
1331 			(fname == NULL)? integrity_results : fname);
1332 		}
1333 		free(errp);
1334 		goto fail;
1335 	}
1336 
1337 	/*
1338 	 * check if we are writable
1339 	 */
1340 	r = backend_is_readonly(be->be_db, be->be_path);
1341 
1342 	if (r == SQLITE_BUSY || r == SQLITE_LOCKED) {
1343 		free(errp);
1344 		*bep = NULL;
1345 		backend_destroy(be);
1346 		return (BACKEND_CREATE_LOCKED);
1347 	}
1348 	if (r != SQLITE_OK && r != SQLITE_FULL) {
1349 		free(errp);
1350 		be->be_readonly = 1;
1351 		*bep = be;
1352 		return (BACKEND_CREATE_READONLY);
1353 	}
1354 	*bep = be;
1355 	return (BACKEND_CREATE_SUCCESS);
1356 
1357 fail:
1358 	*bep = NULL;
1359 	backend_destroy(be);
1360 	return (BACKEND_CREATE_FAIL);
1361 }
1362 
1363 /*
1364  * (arg & -arg) is, through the magic of twos-complement arithmetic, the
1365  * lowest set bit in arg.
1366  */
1367 static size_t
1368 round_up_to_p2(size_t arg)
1369 {
1370 	/*
1371 	 * Don't allow a zero result.
1372 	 */
1373 	assert(arg > 0 && ((ssize_t)arg > 0));
1374 
1375 	while ((arg & (arg - 1)) != 0)
1376 		arg += (arg & -arg);
1377 
1378 	return (arg);
1379 }
1380 
1381 /*
1382  * Returns
1383  *   _NO_RESOURCES - out of memory
1384  *   _BACKEND_ACCESS - backend type t (other than _NORMAL) doesn't exist
1385  *   _DONE - callback aborted query
1386  *   _SUCCESS
1387  */
1388 int
1389 backend_run(backend_type_t t, backend_query_t *q,
1390     backend_run_callback_f *cb, void *data)
1391 {
1392 	char *errmsg = NULL;
1393 	int ret;
1394 	sqlite_backend_t *be;
1395 	hrtime_t ts, vts;
1396 
1397 	if (q == NULL || q->bq_buf == NULL)
1398 		return (REP_PROTOCOL_FAIL_NO_RESOURCES);
1399 
1400 	if ((ret = backend_lock(t, 0, &be)) != REP_PROTOCOL_SUCCESS)
1401 		return (ret);
1402 
1403 	ts = gethrtime();
1404 	vts = gethrvtime();
1405 	ret = sqlite_exec(be->be_db, q->bq_buf, cb, data, &errmsg);
1406 	UPDATE_TOTALS(be, bt_exec, ts, vts);
1407 	ret = backend_error(be, ret, errmsg);
1408 	backend_unlock(be);
1409 
1410 	return (ret);
1411 }
1412 
1413 /*
1414  * Starts a "read-only" transaction -- i.e., locks out writers as long
1415  * as it is active.
1416  *
1417  * Fails with
1418  *   _NO_RESOURCES - out of memory
1419  *
1420  * If t is not _NORMAL, can also fail with
1421  *   _BACKEND_ACCESS - backend does not exist
1422  *
1423  * If writable is true, can also fail with
1424  *   _BACKEND_READONLY
1425  */
1426 static int
1427 backend_tx_begin_common(backend_type_t t, backend_tx_t **txp, int writable)
1428 {
1429 	backend_tx_t *ret;
1430 	sqlite_backend_t *be;
1431 	int r;
1432 
1433 	*txp = NULL;
1434 
1435 	ret = uu_zalloc(sizeof (*ret));
1436 	if (ret == NULL)
1437 		return (REP_PROTOCOL_FAIL_NO_RESOURCES);
1438 
1439 	if ((r = backend_lock(t, writable, &be)) != REP_PROTOCOL_SUCCESS) {
1440 		uu_free(ret);
1441 		return (r);
1442 	}
1443 
1444 	ret->bt_be = be;
1445 	ret->bt_readonly = !writable;
1446 	ret->bt_type = t;
1447 	ret->bt_full = 0;
1448 
1449 	*txp = ret;
1450 	return (REP_PROTOCOL_SUCCESS);
1451 }
1452 
1453 int
1454 backend_tx_begin_ro(backend_type_t t, backend_tx_t **txp)
1455 {
1456 	return (backend_tx_begin_common(t, txp, 0));
1457 }
1458 
1459 static void
1460 backend_tx_end(backend_tx_t *tx)
1461 {
1462 	sqlite_backend_t *be;
1463 
1464 	be = tx->bt_be;
1465 
1466 	if (tx->bt_full) {
1467 		struct sqlite *new;
1468 
1469 		/*
1470 		 * sqlite tends to be sticky with SQLITE_FULL, so we try
1471 		 * to get a fresh database handle if we got a FULL warning
1472 		 * along the way.  If that fails, no harm done.
1473 		 */
1474 		new = sqlite_open(be->be_path, 0600, NULL);
1475 		if (new != NULL) {
1476 			sqlite_close(be->be_db);
1477 			be->be_db = new;
1478 		}
1479 	}
1480 	backend_unlock(be);
1481 	tx->bt_be = NULL;
1482 	uu_free(tx);
1483 }
1484 
1485 void
1486 backend_tx_end_ro(backend_tx_t *tx)
1487 {
1488 	assert(tx->bt_readonly);
1489 	backend_tx_end(tx);
1490 }
1491 
1492 /*
1493  * Fails with
1494  *   _NO_RESOURCES - out of memory
1495  *   _BACKEND_ACCESS
1496  *   _BACKEND_READONLY
1497  */
1498 int
1499 backend_tx_begin(backend_type_t t, backend_tx_t **txp)
1500 {
1501 	int r;
1502 	char *errmsg;
1503 	hrtime_t ts, vts;
1504 
1505 	r = backend_tx_begin_common(t, txp, 1);
1506 	if (r != REP_PROTOCOL_SUCCESS)
1507 		return (r);
1508 
1509 	ts = gethrtime();
1510 	vts = gethrvtime();
1511 	r = sqlite_exec((*txp)->bt_be->be_db, "BEGIN TRANSACTION", NULL, NULL,
1512 	    &errmsg);
1513 	UPDATE_TOTALS((*txp)->bt_be, bt_exec, ts, vts);
1514 	if (r == SQLITE_FULL)
1515 		(*txp)->bt_full = 1;
1516 	r = backend_error((*txp)->bt_be, r, errmsg);
1517 
1518 	if (r != REP_PROTOCOL_SUCCESS) {
1519 		assert(r != REP_PROTOCOL_DONE);
1520 		(void) sqlite_exec((*txp)->bt_be->be_db,
1521 		    "ROLLBACK TRANSACTION", NULL, NULL, NULL);
1522 		backend_tx_end(*txp);
1523 		*txp = NULL;
1524 		return (r);
1525 	}
1526 
1527 	(*txp)->bt_readonly = 0;
1528 
1529 	return (REP_PROTOCOL_SUCCESS);
1530 }
1531 
1532 void
1533 backend_tx_rollback(backend_tx_t *tx)
1534 {
1535 	int r;
1536 	char *errmsg;
1537 	sqlite_backend_t *be;
1538 	hrtime_t ts, vts;
1539 
1540 	assert(tx != NULL && tx->bt_be != NULL && !tx->bt_readonly);
1541 	be = tx->bt_be;
1542 
1543 	ts = gethrtime();
1544 	vts = gethrvtime();
1545 	r = sqlite_exec(be->be_db, "ROLLBACK TRANSACTION", NULL, NULL,
1546 	    &errmsg);
1547 	UPDATE_TOTALS(be, bt_exec, ts, vts);
1548 	if (r == SQLITE_FULL)
1549 		tx->bt_full = 1;
1550 	(void) backend_error(be, r, errmsg);
1551 
1552 	backend_tx_end(tx);
1553 }
1554 
1555 /*
1556  * Fails with
1557  *   _NO_RESOURCES - out of memory
1558  */
1559 int
1560 backend_tx_commit(backend_tx_t *tx)
1561 {
1562 	int r, r2;
1563 	char *errmsg;
1564 	sqlite_backend_t *be;
1565 	hrtime_t ts, vts;
1566 
1567 	assert(tx != NULL && tx->bt_be != NULL && !tx->bt_readonly);
1568 	be = tx->bt_be;
1569 	ts = gethrtime();
1570 	vts = gethrvtime();
1571 	r = sqlite_exec(be->be_db, "COMMIT TRANSACTION", NULL, NULL,
1572 	    &errmsg);
1573 	UPDATE_TOTALS(be, bt_exec, ts, vts);
1574 	if (r == SQLITE_FULL)
1575 		tx->bt_full = 1;
1576 
1577 	r = backend_error(be, r, errmsg);
1578 	assert(r != REP_PROTOCOL_DONE);
1579 
1580 	if (r != REP_PROTOCOL_SUCCESS) {
1581 		r2 = sqlite_exec(be->be_db, "ROLLBACK TRANSACTION", NULL, NULL,
1582 		    &errmsg);
1583 		r2 = backend_error(be, r2, errmsg);
1584 		if (r2 != REP_PROTOCOL_SUCCESS)
1585 			backend_panic("cannot rollback failed commit");
1586 
1587 		backend_tx_end(tx);
1588 		return (r);
1589 	}
1590 	backend_tx_end(tx);
1591 	return (REP_PROTOCOL_SUCCESS);
1592 }
1593 
1594 static const char *
1595 id_space_to_name(enum id_space id)
1596 {
1597 	switch (id) {
1598 	case BACKEND_ID_SERVICE_INSTANCE:
1599 		return ("SI");
1600 	case BACKEND_ID_PROPERTYGRP:
1601 		return ("PG");
1602 	case BACKEND_ID_GENERATION:
1603 		return ("GEN");
1604 	case BACKEND_ID_PROPERTY:
1605 		return ("PROP");
1606 	case BACKEND_ID_VALUE:
1607 		return ("VAL");
1608 	case BACKEND_ID_SNAPNAME:
1609 		return ("SNAME");
1610 	case BACKEND_ID_SNAPSHOT:
1611 		return ("SHOT");
1612 	case BACKEND_ID_SNAPLEVEL:
1613 		return ("SLVL");
1614 	default:
1615 		abort();
1616 		/*NOTREACHED*/
1617 	}
1618 }
1619 
1620 /*
1621  * Returns a new id or 0 if the id argument is invalid or the query fails.
1622  */
1623 uint32_t
1624 backend_new_id(backend_tx_t *tx, enum id_space id)
1625 {
1626 	struct run_single_int_info info;
1627 	uint32_t new_id = 0;
1628 	const char *name = id_space_to_name(id);
1629 	char *errmsg;
1630 	int ret;
1631 	sqlite_backend_t *be;
1632 	hrtime_t ts, vts;
1633 
1634 	assert(tx != NULL && tx->bt_be != NULL && !tx->bt_readonly);
1635 	be = tx->bt_be;
1636 
1637 	info.rs_out = &new_id;
1638 	info.rs_result = REP_PROTOCOL_FAIL_NOT_FOUND;
1639 
1640 	ts = gethrtime();
1641 	vts = gethrvtime();
1642 	ret = sqlite_exec_printf(be->be_db,
1643 	    "SELECT id_next FROM id_tbl WHERE (id_name = '%q');"
1644 	    "UPDATE id_tbl SET id_next = id_next + 1 WHERE (id_name = '%q');",
1645 	    run_single_int_callback, &info, &errmsg, name, name);
1646 	UPDATE_TOTALS(be, bt_exec, ts, vts);
1647 	if (ret == SQLITE_FULL)
1648 		tx->bt_full = 1;
1649 
1650 	ret = backend_error(be, ret, errmsg);
1651 
1652 	if (ret != REP_PROTOCOL_SUCCESS) {
1653 		return (0);
1654 	}
1655 
1656 	return (new_id);
1657 }
1658 
1659 /*
1660  * Returns
1661  *   _NO_RESOURCES - out of memory
1662  *   _DONE - callback aborted query
1663  *   _SUCCESS
1664  */
1665 int
1666 backend_tx_run(backend_tx_t *tx, backend_query_t *q,
1667     backend_run_callback_f *cb, void *data)
1668 {
1669 	char *errmsg = NULL;
1670 	int ret;
1671 	sqlite_backend_t *be;
1672 	hrtime_t ts, vts;
1673 
1674 	assert(tx != NULL && tx->bt_be != NULL);
1675 	be = tx->bt_be;
1676 
1677 	if (q == NULL || q->bq_buf == NULL)
1678 		return (REP_PROTOCOL_FAIL_NO_RESOURCES);
1679 
1680 	ts = gethrtime();
1681 	vts = gethrvtime();
1682 	ret = sqlite_exec(be->be_db, q->bq_buf, cb, data, &errmsg);
1683 	UPDATE_TOTALS(be, bt_exec, ts, vts);
1684 	if (ret == SQLITE_FULL)
1685 		tx->bt_full = 1;
1686 	ret = backend_error(be, ret, errmsg);
1687 
1688 	return (ret);
1689 }
1690 
1691 /*
1692  * Returns
1693  *   _NO_RESOURCES - out of memory
1694  *   _NOT_FOUND - the query returned no results
1695  *   _SUCCESS - the query returned a single integer
1696  */
1697 int
1698 backend_tx_run_single_int(backend_tx_t *tx, backend_query_t *q, uint32_t *buf)
1699 {
1700 	struct run_single_int_info info;
1701 	int ret;
1702 
1703 	info.rs_out = buf;
1704 	info.rs_result = REP_PROTOCOL_FAIL_NOT_FOUND;
1705 
1706 	ret = backend_tx_run(tx, q, run_single_int_callback, &info);
1707 	assert(ret != REP_PROTOCOL_DONE);
1708 
1709 	if (ret != REP_PROTOCOL_SUCCESS)
1710 		return (ret);
1711 
1712 	return (info.rs_result);
1713 }
1714 
1715 /*
1716  * Fails with
1717  *   _NO_RESOURCES - out of memory
1718  */
1719 int
1720 backend_tx_run_update(backend_tx_t *tx, const char *format, ...)
1721 {
1722 	va_list a;
1723 	char *errmsg;
1724 	int ret;
1725 	sqlite_backend_t *be;
1726 	hrtime_t ts, vts;
1727 
1728 	assert(tx != NULL && tx->bt_be != NULL && !tx->bt_readonly);
1729 	be = tx->bt_be;
1730 
1731 	va_start(a, format);
1732 	ts = gethrtime();
1733 	vts = gethrvtime();
1734 	ret = sqlite_exec_vprintf(be->be_db, format, NULL, NULL, &errmsg, a);
1735 	UPDATE_TOTALS(be, bt_exec, ts, vts);
1736 	if (ret == SQLITE_FULL)
1737 		tx->bt_full = 1;
1738 	va_end(a);
1739 	ret = backend_error(be, ret, errmsg);
1740 	assert(ret != REP_PROTOCOL_DONE);
1741 
1742 	return (ret);
1743 }
1744 
1745 /*
1746  * returns REP_PROTOCOL_FAIL_NOT_FOUND if no changes occured
1747  */
1748 int
1749 backend_tx_run_update_changed(backend_tx_t *tx, const char *format, ...)
1750 {
1751 	va_list a;
1752 	char *errmsg;
1753 	int ret;
1754 	sqlite_backend_t *be;
1755 	hrtime_t ts, vts;
1756 
1757 	assert(tx != NULL && tx->bt_be != NULL && !tx->bt_readonly);
1758 	be = tx->bt_be;
1759 
1760 	va_start(a, format);
1761 	ts = gethrtime();
1762 	vts = gethrvtime();
1763 	ret = sqlite_exec_vprintf(be->be_db, format, NULL, NULL, &errmsg, a);
1764 	UPDATE_TOTALS(be, bt_exec, ts, vts);
1765 	if (ret == SQLITE_FULL)
1766 		tx->bt_full = 1;
1767 	va_end(a);
1768 
1769 	ret = backend_error(be, ret, errmsg);
1770 
1771 	return (ret);
1772 }
1773 
1774 #define	BACKEND_ADD_SCHEMA(be, file, tbls, idxs) \
1775 	(backend_add_schema((be), (file), \
1776 	    (tbls), sizeof (tbls) / sizeof (*(tbls)), \
1777 	    (idxs), sizeof (idxs) / sizeof (*(idxs))))
1778 
1779 static int
1780 backend_add_schema(sqlite_backend_t *be, const char *file,
1781     struct backend_tbl_info *tbls, int tbl_count,
1782     struct backend_idx_info *idxs, int idx_count)
1783 {
1784 	int i;
1785 	char *errmsg;
1786 	int ret;
1787 
1788 	/*
1789 	 * Create the tables.
1790 	 */
1791 	for (i = 0; i < tbl_count; i++) {
1792 		if (tbls[i].bti_name == NULL) {
1793 			assert(i + 1 == tbl_count);
1794 			break;
1795 		}
1796 		ret = sqlite_exec_printf(be->be_db,
1797 		    "CREATE TABLE %s (%s);\n",
1798 		    NULL, NULL, &errmsg, tbls[i].bti_name, tbls[i].bti_cols);
1799 
1800 		if (ret != SQLITE_OK) {
1801 			configd_critical(
1802 			    "%s: %s table creation fails: %s\n", file,
1803 			    tbls[i].bti_name, errmsg);
1804 			free(errmsg);
1805 			return (-1);
1806 		}
1807 	}
1808 
1809 	/*
1810 	 * Make indices on key tables and columns.
1811 	 */
1812 	for (i = 0; i < idx_count; i++) {
1813 		if (idxs[i].bxi_tbl == NULL) {
1814 			assert(i + 1 == idx_count);
1815 			break;
1816 		}
1817 
1818 		ret = sqlite_exec_printf(be->be_db,
1819 		    "CREATE INDEX %s_%s ON %s (%s);\n",
1820 		    NULL, NULL, &errmsg, idxs[i].bxi_tbl, idxs[i].bxi_idx,
1821 		    idxs[i].bxi_tbl, idxs[i].bxi_cols);
1822 
1823 		if (ret != SQLITE_OK) {
1824 			configd_critical(
1825 			    "%s: %s_%s index creation fails: %s\n", file,
1826 			    idxs[i].bxi_tbl, idxs[i].bxi_idx, errmsg);
1827 			free(errmsg);
1828 			return (-1);
1829 		}
1830 	}
1831 	return (0);
1832 }
1833 
1834 static int
1835 backend_init_schema(sqlite_backend_t *be, const char *db_file, backend_type_t t)
1836 {
1837 	int i;
1838 	char *errmsg;
1839 	int ret;
1840 
1841 	assert(t == BACKEND_TYPE_NORMAL || t == BACKEND_TYPE_NONPERSIST);
1842 
1843 	if (t == BACKEND_TYPE_NORMAL) {
1844 		ret = BACKEND_ADD_SCHEMA(be, db_file, tbls_normal, idxs_normal);
1845 	} else if (t == BACKEND_TYPE_NONPERSIST) {
1846 		ret = BACKEND_ADD_SCHEMA(be, db_file, tbls_np, idxs_np);
1847 	} else {
1848 		abort();		/* can't happen */
1849 	}
1850 
1851 	if (ret < 0) {
1852 		return (ret);
1853 	}
1854 
1855 	ret = BACKEND_ADD_SCHEMA(be, db_file, tbls_common, idxs_common);
1856 	if (ret < 0) {
1857 		return (ret);
1858 	}
1859 
1860 	/*
1861 	 * Add the schema version to the table
1862 	 */
1863 	ret = sqlite_exec_printf(be->be_db,
1864 	    "INSERT INTO schema_version (schema_version) VALUES (%d)",
1865 	    NULL, NULL, &errmsg, BACKEND_SCHEMA_VERSION);
1866 	if (ret != SQLITE_OK) {
1867 		configd_critical(
1868 		    "setting schema version fails: %s\n", errmsg);
1869 		free(errmsg);
1870 	}
1871 
1872 	/*
1873 	 * Populate id_tbl with initial IDs.
1874 	 */
1875 	for (i = 0; i < BACKEND_ID_INVALID; i++) {
1876 		const char *name = id_space_to_name(i);
1877 
1878 		ret = sqlite_exec_printf(be->be_db,
1879 		    "INSERT INTO id_tbl (id_name, id_next) "
1880 		    "VALUES ('%q', %d);", NULL, NULL, &errmsg, name, 1);
1881 		if (ret != SQLITE_OK) {
1882 			configd_critical(
1883 			    "id insertion for %s fails: %s\n", name, errmsg);
1884 			free(errmsg);
1885 			return (-1);
1886 		}
1887 	}
1888 	/*
1889 	 * Set the persistance of the database.  The normal database is marked
1890 	 * "synchronous", so that all writes are synchronized to stable storage
1891 	 * before proceeding.
1892 	 */
1893 	ret = sqlite_exec_printf(be->be_db,
1894 	    "PRAGMA default_synchronous = %s; PRAGMA synchronous = %s;",
1895 	    NULL, NULL, &errmsg,
1896 	    (t == BACKEND_TYPE_NORMAL)? "ON" : "OFF",
1897 	    (t == BACKEND_TYPE_NORMAL)? "ON" : "OFF");
1898 	if (ret != SQLITE_OK) {
1899 		configd_critical("pragma setting fails: %s\n", errmsg);
1900 		free(errmsg);
1901 		return (-1);
1902 	}
1903 
1904 	return (0);
1905 }
1906 
1907 int
1908 backend_init(const char *db_file, const char *npdb_file, int have_np)
1909 {
1910 	sqlite_backend_t *be;
1911 	int r;
1912 	int writable_persist = 1;
1913 
1914 	/* set up our temporary directory */
1915 	sqlite_temp_directory = "/etc/svc/volatile";
1916 
1917 	if (strcmp(SQLITE_VERSION, sqlite_version) != 0) {
1918 		configd_critical("Mismatched link!  (%s should be %s)\n",
1919 		    sqlite_version, SQLITE_VERSION);
1920 		return (CONFIGD_EXIT_DATABASE_INIT_FAILED);
1921 	}
1922 	if (db_file == NULL)
1923 		db_file = REPOSITORY_DB;
1924 
1925 	r = backend_create(BACKEND_TYPE_NORMAL, db_file, &be);
1926 	switch (r) {
1927 	case BACKEND_CREATE_FAIL:
1928 		return (CONFIGD_EXIT_DATABASE_INIT_FAILED);
1929 	case BACKEND_CREATE_LOCKED:
1930 		return (CONFIGD_EXIT_DATABASE_LOCKED);
1931 	case BACKEND_CREATE_SUCCESS:
1932 		break;		/* success */
1933 	case BACKEND_CREATE_READONLY:
1934 		writable_persist = 0;
1935 		break;
1936 	case BACKEND_CREATE_NEED_INIT:
1937 		if (backend_init_schema(be, db_file, BACKEND_TYPE_NORMAL)) {
1938 			backend_destroy(be);
1939 			return (CONFIGD_EXIT_DATABASE_INIT_FAILED);
1940 		}
1941 		break;
1942 	default:
1943 		abort();
1944 		/*NOTREACHED*/
1945 	}
1946 	backend_create_finish(BACKEND_TYPE_NORMAL, be);
1947 
1948 	if (have_np) {
1949 		if (npdb_file == NULL)
1950 			npdb_file = NONPERSIST_DB;
1951 
1952 		r = backend_create(BACKEND_TYPE_NONPERSIST, npdb_file, &be);
1953 		switch (r) {
1954 		case BACKEND_CREATE_SUCCESS:
1955 			break;		/* success */
1956 		case BACKEND_CREATE_FAIL:
1957 			return (CONFIGD_EXIT_DATABASE_INIT_FAILED);
1958 		case BACKEND_CREATE_LOCKED:
1959 			return (CONFIGD_EXIT_DATABASE_LOCKED);
1960 		case BACKEND_CREATE_READONLY:
1961 			configd_critical("%s: unable to write\n", npdb_file);
1962 			return (CONFIGD_EXIT_DATABASE_INIT_FAILED);
1963 		case BACKEND_CREATE_NEED_INIT:
1964 			if (backend_init_schema(be, db_file,
1965 			    BACKEND_TYPE_NONPERSIST)) {
1966 				backend_destroy(be);
1967 				return (CONFIGD_EXIT_DATABASE_INIT_FAILED);
1968 			}
1969 			break;
1970 		default:
1971 			abort();
1972 			/*NOTREACHED*/
1973 		}
1974 		backend_create_finish(BACKEND_TYPE_NONPERSIST, be);
1975 
1976 		/*
1977 		 * If we started up with a writable filesystem, but the
1978 		 * non-persistent database needed initialization, we
1979 		 * are booting a non-global zone, so do a backup.
1980 		 */
1981 		if (r == BACKEND_CREATE_NEED_INIT && writable_persist &&
1982 		    backend_lock(BACKEND_TYPE_NORMAL, 0, &be) ==
1983 		    REP_PROTOCOL_SUCCESS) {
1984 			if (backend_create_backup_locked(be,
1985 			    REPOSITORY_BOOT_BACKUP) != REP_PROTOCOL_SUCCESS) {
1986 				configd_critical(
1987 				    "unable to create \"%s\" backup of "
1988 				    "\"%s\"\n", REPOSITORY_BOOT_BACKUP,
1989 				    be->be_path);
1990 			}
1991 			backend_unlock(be);
1992 		}
1993 	}
1994 	return (CONFIGD_EXIT_OKAY);
1995 }
1996 
1997 /*
1998  * quiesce all database activity prior to exiting
1999  */
2000 void
2001 backend_fini(void)
2002 {
2003 	sqlite_backend_t *be_normal, *be_np;
2004 
2005 	(void) backend_lock(BACKEND_TYPE_NORMAL, 1, &be_normal);
2006 	(void) backend_lock(BACKEND_TYPE_NONPERSIST, 1, &be_np);
2007 }
2008 
2009 #define	QUERY_BASE	128
2010 backend_query_t *
2011 backend_query_alloc(void)
2012 {
2013 	backend_query_t *q;
2014 	q = calloc(1, sizeof (backend_query_t));
2015 	if (q != NULL) {
2016 		q->bq_size = QUERY_BASE;
2017 		q->bq_buf = calloc(1, q->bq_size);
2018 		if (q->bq_buf == NULL) {
2019 			q->bq_size = 0;
2020 		}
2021 
2022 	}
2023 	return (q);
2024 }
2025 
2026 void
2027 backend_query_append(backend_query_t *q, const char *value)
2028 {
2029 	char *alloc;
2030 	int count;
2031 	size_t size, old_len;
2032 
2033 	if (q == NULL) {
2034 		/* We'll discover the error when we try to run the query. */
2035 		return;
2036 	}
2037 
2038 	while (q->bq_buf != NULL) {
2039 		old_len = strlen(q->bq_buf);
2040 		size = q->bq_size;
2041 		count = strlcat(q->bq_buf, value, size);
2042 
2043 		if (count < size)
2044 			break;				/* success */
2045 
2046 		q->bq_buf[old_len] = 0;
2047 		size = round_up_to_p2(count + 1);
2048 
2049 		assert(size > q->bq_size);
2050 		alloc = realloc(q->bq_buf, size);
2051 		if (alloc == NULL) {
2052 			free(q->bq_buf);
2053 			q->bq_buf = NULL;
2054 			break;				/* can't grow */
2055 		}
2056 
2057 		q->bq_buf = alloc;
2058 		q->bq_size = size;
2059 	}
2060 }
2061 
2062 void
2063 backend_query_add(backend_query_t *q, const char *format, ...)
2064 {
2065 	va_list args;
2066 	char *new;
2067 
2068 	if (q == NULL || q->bq_buf == NULL)
2069 		return;
2070 
2071 	va_start(args, format);
2072 	new = sqlite_vmprintf(format, args);
2073 	va_end(args);
2074 
2075 	if (new == NULL) {
2076 		free(q->bq_buf);
2077 		q->bq_buf = NULL;
2078 		return;
2079 	}
2080 
2081 	backend_query_append(q, new);
2082 
2083 	free(new);
2084 }
2085 
2086 void
2087 backend_query_free(backend_query_t *q)
2088 {
2089 	if (q != NULL) {
2090 		if (q->bq_buf != NULL) {
2091 			free(q->bq_buf);
2092 		}
2093 		free(q);
2094 	}
2095 }
2096