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