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