1 /* $NetBSD: toolcontext.c,v 1.4 2009/02/18 12:16:13 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 * 7 * This file is part of LVM2. 8 * 9 * This copyrighted material is made available to anyone wishing to use, 10 * modify, copy, or redistribute it subject to the terms and conditions 11 * of the GNU Lesser General Public License v.2.1. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software Foundation, 15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 #include "lib.h" 19 #include "toolcontext.h" 20 #include "metadata.h" 21 #include "defaults.h" 22 #include "lvm-string.h" 23 #include "activate.h" 24 #include "filter.h" 25 #include "filter-composite.h" 26 #include "filter-md.h" 27 #include "filter-persistent.h" 28 #include "filter-regex.h" 29 #include "filter-sysfs.h" 30 #include "label.h" 31 #include "lvm-file.h" 32 #include "format-text.h" 33 #include "display.h" 34 #include "memlock.h" 35 #include "str_list.h" 36 #include "segtype.h" 37 #include "lvmcache.h" 38 #include "dev-cache.h" 39 #include "archiver.h" 40 41 #ifdef HAVE_LIBDL 42 #include "sharedlib.h" 43 #endif 44 45 #ifdef LVM1_INTERNAL 46 #include "format1.h" 47 #endif 48 49 #ifdef POOL_INTERNAL 50 #include "format_pool.h" 51 #endif 52 53 #include <locale.h> 54 #include <sys/stat.h> 55 #include <sys/utsname.h> 56 #include <syslog.h> 57 #include <time.h> 58 59 #ifdef linux 60 # include <malloc.h> 61 #endif 62 63 static int _get_env_vars(struct cmd_context *cmd) 64 { 65 const char *e; 66 67 /* Set to "" to avoid using any system directory */ 68 if ((e = getenv("LVM_SYSTEM_DIR"))) { 69 if (dm_snprintf(cmd->sys_dir, sizeof(cmd->sys_dir), 70 "%s", e) < 0) { 71 log_error("LVM_SYSTEM_DIR environment variable " 72 "is too long."); 73 return 0; 74 } 75 } 76 77 return 1; 78 } 79 80 static void _get_sysfs_dir(struct cmd_context *cmd) 81 { 82 static char proc_mounts[PATH_MAX]; 83 static char *split[4], buffer[PATH_MAX + 16]; 84 FILE *fp; 85 char *sys_mnt = NULL; 86 87 cmd->sysfs_dir[0] = '\0'; 88 if (!*cmd->proc_dir) { 89 log_debug("No proc filesystem found: skipping sysfs detection"); 90 return; 91 } 92 93 if (dm_snprintf(proc_mounts, sizeof(proc_mounts), 94 "%s/mounts", cmd->proc_dir) < 0) { 95 log_error("Failed to create /proc/mounts string for sysfs detection"); 96 return; 97 } 98 99 if (!(fp = fopen(proc_mounts, "r"))) { 100 log_sys_error("_get_sysfs_dir: fopen %s", proc_mounts); 101 return; 102 } 103 104 while (fgets(buffer, sizeof(buffer), fp)) { 105 if (dm_split_words(buffer, 4, 0, split) == 4 && 106 !strcmp(split[2], "sysfs")) { 107 sys_mnt = split[1]; 108 break; 109 } 110 } 111 112 if (fclose(fp)) 113 log_sys_error("fclose", proc_mounts); 114 115 if (!sys_mnt) { 116 log_error("Failed to find sysfs mount point"); 117 return; 118 } 119 120 strncpy(cmd->sysfs_dir, sys_mnt, sizeof(cmd->sysfs_dir)); 121 } 122 123 static void _init_logging(struct cmd_context *cmd) 124 { 125 int append = 1; 126 time_t t; 127 128 const char *log_file; 129 char timebuf[26]; 130 131 /* Syslog */ 132 cmd->default_settings.syslog = 133 find_config_tree_int(cmd, "log/syslog", DEFAULT_SYSLOG); 134 if (cmd->default_settings.syslog != 1) 135 fin_syslog(); 136 137 if (cmd->default_settings.syslog > 1) 138 init_syslog(cmd->default_settings.syslog); 139 140 /* Debug level for log file output */ 141 cmd->default_settings.debug = 142 find_config_tree_int(cmd, "log/level", DEFAULT_LOGLEVEL); 143 init_debug(cmd->default_settings.debug); 144 145 /* Verbose level for tty output */ 146 cmd->default_settings.verbose = 147 find_config_tree_int(cmd, "log/verbose", DEFAULT_VERBOSE); 148 init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL); 149 150 /* Log message formatting */ 151 init_indent(find_config_tree_int(cmd, "log/indent", 152 DEFAULT_INDENT)); 153 154 cmd->default_settings.msg_prefix = find_config_tree_str(cmd, 155 "log/prefix", 156 DEFAULT_MSG_PREFIX); 157 init_msg_prefix(cmd->default_settings.msg_prefix); 158 159 cmd->default_settings.cmd_name = find_config_tree_int(cmd, 160 "log/command_names", 161 DEFAULT_CMD_NAME); 162 init_cmd_name(cmd->default_settings.cmd_name); 163 164 /* Test mode */ 165 cmd->default_settings.test = 166 find_config_tree_int(cmd, "global/test", 0); 167 init_test(cmd->default_settings.test); 168 169 /* Settings for logging to file */ 170 if (find_config_tree_int(cmd, "log/overwrite", DEFAULT_OVERWRITE)) 171 append = 0; 172 173 log_file = find_config_tree_str(cmd, "log/file", 0); 174 175 if (log_file) { 176 release_log_memory(); 177 fin_log(); 178 init_log_file(log_file, append); 179 } 180 181 log_file = find_config_tree_str(cmd, "log/activate_file", 0); 182 if (log_file) 183 init_log_direct(log_file, append); 184 185 init_log_while_suspended(find_config_tree_int(cmd, 186 "log/activation", 0)); 187 188 t = time(NULL); 189 ctime_r(&t, &timebuf[0]); 190 timebuf[24] = '\0'; 191 log_verbose("Logging initialised at %s", timebuf); 192 193 /* Tell device-mapper about our logging */ 194 #ifdef DEVMAPPER_SUPPORT 195 dm_log_init(print_log); 196 #endif 197 } 198 199 static int _process_config(struct cmd_context *cmd) 200 { 201 mode_t old_umask; 202 const char *read_ahead; 203 struct stat st; 204 205 /* umask */ 206 cmd->default_settings.umask = find_config_tree_int(cmd, 207 "global/umask", 208 DEFAULT_UMASK); 209 210 if ((old_umask = umask((mode_t) cmd->default_settings.umask)) != 211 (mode_t) cmd->default_settings.umask) 212 log_verbose("Set umask to %04o", cmd->default_settings.umask); 213 214 /* dev dir */ 215 if (dm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/", 216 find_config_tree_str(cmd, "devices/dir", 217 DEFAULT_DEV_DIR)) < 0) { 218 log_error("Device directory given in config file too long"); 219 return 0; 220 } 221 #ifdef DEVMAPPER_SUPPORT 222 dm_set_dev_dir(cmd->dev_dir); 223 #endif 224 #ifndef __NetBSD__ 225 /* proc dir */ 226 if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s", 227 find_config_tree_str(cmd, "global/proc", 228 DEFAULT_PROC_DIR)) < 0) { 229 log_error("Device directory given in config file too long"); 230 return 0; 231 } 232 #endif 233 if (*cmd->proc_dir && !dir_exists(cmd->proc_dir)) { 234 log_error("WARNING: proc dir %s not found - some checks will be bypassed", 235 cmd->proc_dir); 236 *cmd->proc_dir = '\0'; 237 } 238 239 _get_sysfs_dir(cmd); 240 241 /* activation? */ 242 cmd->default_settings.activation = find_config_tree_int(cmd, 243 "global/activation", 244 DEFAULT_ACTIVATION); 245 set_activation(cmd->default_settings.activation); 246 247 cmd->default_settings.suffix = find_config_tree_int(cmd, 248 "global/suffix", 249 DEFAULT_SUFFIX); 250 251 if (!(cmd->default_settings.unit_factor = 252 units_to_bytes(find_config_tree_str(cmd, 253 "global/units", 254 DEFAULT_UNITS), 255 &cmd->default_settings.unit_type))) { 256 log_error("Invalid units specification"); 257 return 0; 258 } 259 260 read_ahead = find_config_tree_str(cmd, "activation/readahead", DEFAULT_READ_AHEAD); 261 if (!strcasecmp(read_ahead, "auto")) 262 cmd->default_settings.read_ahead = DM_READ_AHEAD_AUTO; 263 else if (!strcasecmp(read_ahead, "none")) 264 cmd->default_settings.read_ahead = DM_READ_AHEAD_NONE; 265 else { 266 log_error("Invalid readahead specification"); 267 return 0; 268 } 269 270 cmd->stripe_filler = find_config_tree_str(cmd, 271 "activation/missing_stripe_filler", 272 DEFAULT_STRIPE_FILLER); 273 274 /* FIXME Missing error code checks from the stats, not log_warn?, notify if setting overridden, delay message/check till it is actually used (eg consider if lvm shell - file could appear later after this check)? */ 275 if (!strcmp(cmd->stripe_filler, "/dev/ioerror") && 276 stat(cmd->stripe_filler, &st)) 277 cmd->stripe_filler = "error"; 278 279 if (strcmp(cmd->stripe_filler, "error")) { 280 if (stat(cmd->stripe_filler, &st)) { 281 log_warn("WARNING: activation/missing_stripe_filler = \"%s\" " 282 "is invalid,", cmd->stripe_filler); 283 log_warn(" stat failed: %s", strerror(errno)); 284 log_warn("Falling back to \"error\" missing_stripe_filler."); 285 cmd->stripe_filler = "error"; 286 } else if (!S_ISBLK(st.st_mode)) { 287 log_warn("WARNING: activation/missing_stripe_filler = \"%s\" " 288 "is not a block device.", cmd->stripe_filler); 289 log_warn("Falling back to \"error\" missing_stripe_filler."); 290 cmd->stripe_filler = "error"; 291 } 292 } 293 294 return 1; 295 } 296 297 static int _set_tag(struct cmd_context *cmd, const char *tag) 298 { 299 log_very_verbose("Setting host tag: %s", dm_pool_strdup(cmd->libmem, tag)); 300 301 if (!str_list_add(cmd->libmem, &cmd->tags, tag)) { 302 log_error("_set_tag: str_list_add %s failed", tag); 303 return 0; 304 } 305 306 return 1; 307 } 308 309 static int _check_host_filters(struct cmd_context *cmd, struct config_node *hn, 310 int *passes) 311 { 312 struct config_node *cn; 313 struct config_value *cv; 314 315 *passes = 1; 316 317 for (cn = hn; cn; cn = cn->sib) { 318 if (!cn->v) 319 continue; 320 if (!strcmp(cn->key, "host_list")) { 321 *passes = 0; 322 if (cn->v->type == CFG_EMPTY_ARRAY) 323 continue; 324 for (cv = cn->v; cv; cv = cv->next) { 325 if (cv->type != CFG_STRING) { 326 log_error("Invalid hostname string " 327 "for tag %s", cn->key); 328 return 0; 329 } 330 if (!strcmp(cv->v.str, cmd->hostname)) { 331 *passes = 1; 332 return 1; 333 } 334 } 335 } 336 if (!strcmp(cn->key, "host_filter")) { 337 log_error("host_filter not supported yet"); 338 return 0; 339 } 340 } 341 342 return 1; 343 } 344 345 static int _init_tags(struct cmd_context *cmd, struct config_tree *cft) 346 { 347 const struct config_node *tn, *cn; 348 const char *tag; 349 int passes; 350 351 if (!(tn = find_config_node(cft->root, "tags")) || !tn->child) 352 return 1; 353 354 /* NB hosttags 0 when already 1 intentionally does not delete the tag */ 355 if (!cmd->hosttags && find_config_int(cft->root, "tags/hosttags", 356 DEFAULT_HOSTTAGS)) { 357 /* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */ 358 if (!_set_tag(cmd, cmd->hostname)) 359 return_0; 360 cmd->hosttags = 1; 361 } 362 363 for (cn = tn->child; cn; cn = cn->sib) { 364 if (cn->v) 365 continue; 366 tag = cn->key; 367 if (*tag == '@') 368 tag++; 369 if (!validate_name(tag)) { 370 log_error("Invalid tag in config file: %s", cn->key); 371 return 0; 372 } 373 if (cn->child) { 374 passes = 0; 375 if (!_check_host_filters(cmd, cn->child, &passes)) 376 return_0; 377 if (!passes) 378 continue; 379 } 380 if (!_set_tag(cmd, tag)) 381 return_0; 382 } 383 384 return 1; 385 } 386 387 static int _load_config_file(struct cmd_context *cmd, const char *tag) 388 { 389 char config_file[PATH_MAX] = ""; 390 const char *filler = ""; 391 struct stat info; 392 struct config_tree_list *cfl; 393 394 if (*tag) 395 filler = "_"; 396 397 if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf", 398 cmd->sys_dir, filler, tag) < 0) { 399 log_error("LVM_SYSTEM_DIR or tag was too long"); 400 return 0; 401 } 402 403 if (!(cfl = dm_pool_alloc(cmd->libmem, sizeof(*cfl)))) { 404 log_error("config_tree_list allocation failed"); 405 return 0; 406 } 407 408 if (!(cfl->cft = create_config_tree(config_file, 0))) { 409 log_error("config_tree allocation failed"); 410 return 0; 411 } 412 413 /* Is there a config file? */ 414 if (stat(config_file, &info) == -1) { 415 if (errno == ENOENT) { 416 dm_list_add(&cmd->config_files, &cfl->list); 417 goto out; 418 } 419 log_sys_error("stat", config_file); 420 destroy_config_tree(cfl->cft); 421 return 0; 422 } 423 424 log_very_verbose("Loading config file: %s", config_file); 425 if (!read_config_file(cfl->cft)) { 426 log_error("Failed to load config file %s", config_file); 427 destroy_config_tree(cfl->cft); 428 return 0; 429 } 430 431 dm_list_add(&cmd->config_files, &cfl->list); 432 433 out: 434 if (*tag) 435 _init_tags(cmd, cfl->cft); 436 else 437 /* Use temporary copy of lvm.conf while loading other files */ 438 cmd->cft = cfl->cft; 439 440 return 1; 441 } 442 443 /* Find and read first config file */ 444 static int _init_lvm_conf(struct cmd_context *cmd) 445 { 446 /* No config file if LVM_SYSTEM_DIR is empty */ 447 if (!*cmd->sys_dir) { 448 if (!(cmd->cft = create_config_tree(NULL, 0))) { 449 log_error("Failed to create config tree"); 450 return 0; 451 } 452 return 1; 453 } 454 455 if (!_load_config_file(cmd, "")) 456 return_0; 457 458 return 1; 459 } 460 461 /* Read any additional config files */ 462 static int _init_tag_configs(struct cmd_context *cmd) 463 { 464 struct str_list *sl; 465 466 /* Tag list may grow while inside this loop */ 467 dm_list_iterate_items(sl, &cmd->tags) { 468 if (!_load_config_file(cmd, sl->str)) 469 return_0; 470 } 471 472 return 1; 473 } 474 475 static int _merge_config_files(struct cmd_context *cmd) 476 { 477 struct config_tree_list *cfl; 478 479 /* Replace temporary duplicate copy of lvm.conf */ 480 if (cmd->cft->root) { 481 if (!(cmd->cft = create_config_tree(NULL, 0))) { 482 log_error("Failed to create config tree"); 483 return 0; 484 } 485 } 486 487 dm_list_iterate_items(cfl, &cmd->config_files) { 488 /* Merge all config trees into cmd->cft using merge/tag rules */ 489 if (!merge_config_tree(cmd, cmd->cft, cfl->cft)) 490 return_0; 491 } 492 493 return 1; 494 } 495 496 static void _destroy_tags(struct cmd_context *cmd) 497 { 498 struct dm_list *slh, *slht; 499 500 dm_list_iterate_safe(slh, slht, &cmd->tags) { 501 dm_list_del(slh); 502 } 503 } 504 505 int config_files_changed(struct cmd_context *cmd) 506 { 507 struct config_tree_list *cfl; 508 509 dm_list_iterate_items(cfl, &cmd->config_files) { 510 if (config_file_changed(cfl->cft)) 511 return 1; 512 } 513 514 return 0; 515 } 516 517 static void _destroy_tag_configs(struct cmd_context *cmd) 518 { 519 struct config_tree_list *cfl; 520 521 if (cmd->cft && cmd->cft->root) { 522 destroy_config_tree(cmd->cft); 523 cmd->cft = NULL; 524 } 525 526 dm_list_iterate_items(cfl, &cmd->config_files) { 527 destroy_config_tree(cfl->cft); 528 } 529 530 dm_list_init(&cmd->config_files); 531 } 532 533 static int _init_dev_cache(struct cmd_context *cmd) 534 { 535 const struct config_node *cn; 536 struct config_value *cv; 537 538 if (!dev_cache_init(cmd)) 539 return_0; 540 541 if (!(cn = find_config_tree_node(cmd, "devices/scan"))) { 542 if (!dev_cache_add_dir("/dev")) { 543 log_error("Failed to add /dev to internal " 544 "device cache"); 545 return 0; 546 } 547 log_verbose("device/scan not in config file: " 548 "Defaulting to /dev"); 549 return 1; 550 } 551 552 for (cv = cn->v; cv; cv = cv->next) { 553 if (cv->type != CFG_STRING) { 554 log_error("Invalid string in config file: " 555 "devices/scan"); 556 return 0; 557 } 558 559 if (!dev_cache_add_dir(cv->v.str)) { 560 log_error("Failed to add %s to internal device cache", 561 cv->v.str); 562 return 0; 563 } 564 } 565 566 if (!(cn = find_config_tree_node(cmd, "devices/loopfiles"))) 567 return 1; 568 569 for (cv = cn->v; cv; cv = cv->next) { 570 if (cv->type != CFG_STRING) { 571 log_error("Invalid string in config file: " 572 "devices/loopfiles"); 573 return 0; 574 } 575 576 if (!dev_cache_add_loopfile(cv->v.str)) { 577 log_error("Failed to add loopfile %s to internal " 578 "device cache", cv->v.str); 579 return 0; 580 } 581 } 582 583 584 return 1; 585 } 586 587 #define MAX_FILTERS 4 588 589 static struct dev_filter *_init_filter_components(struct cmd_context *cmd) 590 { 591 unsigned nr_filt = 0; 592 const struct config_node *cn; 593 struct dev_filter *filters[MAX_FILTERS]; 594 595 memset(filters, 0, sizeof(filters)); 596 597 /* 598 * Filters listed in order: top one gets applied first. 599 * Failure to initialise some filters is not fatal. 600 * Update MAX_FILTERS definition above when adding new filters. 601 */ 602 603 /* 604 * sysfs filter. Only available on 2.6 kernels. Non-critical. 605 * Listed first because it's very efficient at eliminating 606 * unavailable devices. 607 */ 608 if (find_config_tree_bool(cmd, "devices/sysfs_scan", 609 DEFAULT_SYSFS_SCAN)) { 610 if ((filters[nr_filt] = sysfs_filter_create(cmd->sysfs_dir))) 611 nr_filt++; 612 } 613 614 /* regex filter. Optional. */ 615 if (!(cn = find_config_tree_node(cmd, "devices/filter"))) 616 log_very_verbose("devices/filter not found in config file: " 617 "no regex filter installed"); 618 619 else if (!(filters[nr_filt++] = regex_filter_create(cn->v))) { 620 log_error("Failed to create regex device filter"); 621 return NULL; 622 } 623 624 /* device type filter. Required. */ 625 cn = find_config_tree_node(cmd, "devices/types"); 626 if (!(filters[nr_filt++] = lvm_type_filter_create(cmd->proc_dir, cn))) { 627 log_error("Failed to create lvm type filter"); 628 return NULL; 629 } 630 631 /* md component filter. Optional, non-critical. */ 632 if (find_config_tree_bool(cmd, "devices/md_component_detection", 633 DEFAULT_MD_COMPONENT_DETECTION)) { 634 init_md_filtering(1); 635 if ((filters[nr_filt] = md_filter_create())) 636 nr_filt++; 637 } 638 639 /* Only build a composite filter if we really need it. */ 640 return (nr_filt == 1) ? 641 filters[0] : composite_filter_create(nr_filt, filters); 642 } 643 644 static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache) 645 { 646 const char *dev_cache = NULL, *cache_dir, *cache_file_prefix; 647 struct dev_filter *f3, *f4; 648 struct stat st; 649 char cache_file[PATH_MAX]; 650 651 cmd->dump_filter = 0; 652 653 if (!(f3 = _init_filter_components(cmd))) 654 return 0; 655 656 init_ignore_suspended_devices(find_config_tree_int(cmd, 657 "devices/ignore_suspended_devices", DEFAULT_IGNORE_SUSPENDED_DEVICES)); 658 659 /* 660 * If 'cache_dir' or 'cache_file_prefix' is set, ignore 'cache'. 661 */ 662 cache_dir = find_config_tree_str(cmd, "devices/cache_dir", NULL); 663 cache_file_prefix = find_config_tree_str(cmd, "devices/cache_file_prefix", NULL); 664 665 if (cache_dir || cache_file_prefix) { 666 if (dm_snprintf(cache_file, sizeof(cache_file), 667 "%s%s%s/%s.cache", 668 cache_dir ? "" : cmd->sys_dir, 669 cache_dir ? "" : "/", 670 cache_dir ? : DEFAULT_CACHE_SUBDIR, 671 cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) { 672 log_error("Persistent cache filename too long."); 673 return 0; 674 } 675 } else if (!(dev_cache = find_config_tree_str(cmd, "devices/cache", NULL)) && 676 (dm_snprintf(cache_file, sizeof(cache_file), 677 "%s/%s/%s.cache", 678 cmd->sys_dir, DEFAULT_CACHE_SUBDIR, 679 DEFAULT_CACHE_FILE_PREFIX) < 0)) { 680 log_error("Persistent cache filename too long."); 681 return 0; 682 } 683 684 if (!dev_cache) 685 dev_cache = cache_file; 686 687 if (!(f4 = persistent_filter_create(f3, dev_cache))) { 688 log_error("Failed to create persistent device filter"); 689 return 0; 690 } 691 692 /* Should we ever dump persistent filter state? */ 693 if (find_config_tree_int(cmd, "devices/write_cache_state", 1)) 694 cmd->dump_filter = 1; 695 696 if (!*cmd->sys_dir) 697 cmd->dump_filter = 0; 698 699 /* 700 * Only load persistent filter device cache on startup if it is newer 701 * than the config file and this is not a long-lived process. 702 */ 703 if (load_persistent_cache && !cmd->is_long_lived && 704 !stat(dev_cache, &st) && 705 (st.st_ctime > config_file_timestamp(cmd->cft)) && 706 !persistent_filter_load(f4, NULL)) 707 log_verbose("Failed to load existing device cache from %s", 708 dev_cache); 709 710 cmd->filter = f4; 711 712 return 1; 713 } 714 715 static int _init_formats(struct cmd_context *cmd) 716 { 717 const char *format; 718 719 struct format_type *fmt; 720 721 #ifdef HAVE_LIBDL 722 const struct config_node *cn; 723 #endif 724 725 label_init(); 726 727 #ifdef LVM1_INTERNAL 728 if (!(fmt = init_lvm1_format(cmd))) 729 return 0; 730 fmt->library = NULL; 731 dm_list_add(&cmd->formats, &fmt->list); 732 #endif 733 734 #ifdef POOL_INTERNAL 735 if (!(fmt = init_pool_format(cmd))) 736 return 0; 737 fmt->library = NULL; 738 dm_list_add(&cmd->formats, &fmt->list); 739 #endif 740 741 #ifdef HAVE_LIBDL 742 /* Load any formats in shared libs if not static */ 743 if (!is_static() && 744 (cn = find_config_tree_node(cmd, "global/format_libraries"))) { 745 746 struct config_value *cv; 747 struct format_type *(*init_format_fn) (struct cmd_context *); 748 void *lib; 749 750 for (cv = cn->v; cv; cv = cv->next) { 751 if (cv->type != CFG_STRING) { 752 log_error("Invalid string in config file: " 753 "global/format_libraries"); 754 return 0; 755 } 756 if (!(lib = load_shared_library(cmd, cv->v.str, 757 "format", 0))) 758 return_0; 759 760 if (!(init_format_fn = dlsym(lib, "init_format"))) { 761 log_error("Shared library %s does not contain " 762 "format functions", cv->v.str); 763 dlclose(lib); 764 return 0; 765 } 766 767 if (!(fmt = init_format_fn(cmd))) 768 return 0; 769 fmt->library = lib; 770 dm_list_add(&cmd->formats, &fmt->list); 771 } 772 } 773 #endif 774 775 if (!(fmt = create_text_format(cmd))) 776 return 0; 777 fmt->library = NULL; 778 dm_list_add(&cmd->formats, &fmt->list); 779 780 cmd->fmt_backup = fmt; 781 782 format = find_config_tree_str(cmd, "global/format", 783 DEFAULT_FORMAT); 784 785 dm_list_iterate_items(fmt, &cmd->formats) { 786 if (!strcasecmp(fmt->name, format) || 787 (fmt->alias && !strcasecmp(fmt->alias, format))) { 788 cmd->default_settings.fmt = fmt; 789 cmd->fmt = cmd->default_settings.fmt; 790 return 1; 791 } 792 } 793 794 log_error("_init_formats: Default format (%s) not found", format); 795 return 0; 796 } 797 798 int init_lvmcache_orphans(struct cmd_context *cmd) 799 { 800 struct format_type *fmt; 801 802 dm_list_iterate_items(fmt, &cmd->formats) 803 if (!lvmcache_add_orphan_vginfo(fmt->orphan_vg_name, fmt)) 804 return_0; 805 806 return 1; 807 } 808 809 static int _init_segtypes(struct cmd_context *cmd) 810 { 811 struct segment_type *segtype; 812 813 #ifdef HAVE_LIBDL 814 const struct config_node *cn; 815 #endif 816 817 if (!(segtype = init_striped_segtype(cmd))) 818 return 0; 819 segtype->library = NULL; 820 dm_list_add(&cmd->segtypes, &segtype->list); 821 822 if (!(segtype = init_zero_segtype(cmd))) 823 return 0; 824 segtype->library = NULL; 825 dm_list_add(&cmd->segtypes, &segtype->list); 826 827 if (!(segtype = init_error_segtype(cmd))) 828 return 0; 829 segtype->library = NULL; 830 dm_list_add(&cmd->segtypes, &segtype->list); 831 832 if (!(segtype = init_free_segtype(cmd))) 833 return 0; 834 segtype->library = NULL; 835 dm_list_add(&cmd->segtypes, &segtype->list); 836 837 #ifdef SNAPSHOT_INTERNAL 838 if (!(segtype = init_snapshot_segtype(cmd))) 839 return 0; 840 segtype->library = NULL; 841 dm_list_add(&cmd->segtypes, &segtype->list); 842 #endif 843 844 #ifdef MIRRORED_INTERNAL 845 if (!(segtype = init_mirrored_segtype(cmd))) 846 return 0; 847 segtype->library = NULL; 848 dm_list_add(&cmd->segtypes, &segtype->list); 849 #endif 850 851 #ifdef HAVE_LIBDL 852 /* Load any formats in shared libs unless static */ 853 if (!is_static() && 854 (cn = find_config_tree_node(cmd, "global/segment_libraries"))) { 855 856 struct config_value *cv; 857 struct segment_type *(*init_segtype_fn) (struct cmd_context *); 858 void *lib; 859 struct segment_type *segtype2; 860 861 for (cv = cn->v; cv; cv = cv->next) { 862 if (cv->type != CFG_STRING) { 863 log_error("Invalid string in config file: " 864 "global/segment_libraries"); 865 return 0; 866 } 867 if (!(lib = load_shared_library(cmd, cv->v.str, 868 "segment type", 0))) 869 return_0; 870 871 if (!(init_segtype_fn = dlsym(lib, "init_segtype"))) { 872 log_error("Shared library %s does not contain " 873 "segment type functions", cv->v.str); 874 dlclose(lib); 875 return 0; 876 } 877 878 if (!(segtype = init_segtype_fn(cmd))) 879 return 0; 880 segtype->library = lib; 881 dm_list_add(&cmd->segtypes, &segtype->list); 882 883 dm_list_iterate_items(segtype2, &cmd->segtypes) { 884 if ((segtype == segtype2) || 885 strcmp(segtype2->name, segtype->name)) 886 continue; 887 log_error("Duplicate segment type %s: " 888 "unloading shared library %s", 889 segtype->name, cv->v.str); 890 dm_list_del(&segtype->list); 891 segtype->ops->destroy(segtype); 892 dlclose(lib); 893 } 894 } 895 } 896 #endif 897 898 return 1; 899 } 900 901 static int _init_hostname(struct cmd_context *cmd) 902 { 903 struct utsname uts; 904 905 if (uname(&uts)) { 906 log_sys_error("uname", "_init_hostname"); 907 return 0; 908 } 909 910 if (!(cmd->hostname = dm_pool_strdup(cmd->libmem, uts.nodename))) { 911 log_error("_init_hostname: dm_pool_strdup failed"); 912 return 0; 913 } 914 915 if (!(cmd->kernel_vsn = dm_pool_strdup(cmd->libmem, uts.release))) { 916 log_error("_init_hostname: dm_pool_strdup kernel_vsn failed"); 917 return 0; 918 } 919 920 return 1; 921 } 922 923 static int _init_backup(struct cmd_context *cmd) 924 { 925 uint32_t days, min; 926 char default_dir[PATH_MAX]; 927 const char *dir; 928 929 if (!cmd->sys_dir) { 930 log_warn("WARNING: Metadata changes will NOT be backed up"); 931 backup_init(cmd, "", 0); 932 archive_init(cmd, "", 0, 0, 0); 933 return 1; 934 } 935 936 /* set up archiving */ 937 cmd->default_settings.archive = 938 find_config_tree_bool(cmd, "backup/archive", 939 DEFAULT_ARCHIVE_ENABLED); 940 941 days = (uint32_t) find_config_tree_int(cmd, "backup/retain_days", 942 DEFAULT_ARCHIVE_DAYS); 943 944 min = (uint32_t) find_config_tree_int(cmd, "backup/retain_min", 945 DEFAULT_ARCHIVE_NUMBER); 946 947 if (dm_snprintf 948 (default_dir, sizeof(default_dir), "%s/%s", cmd->sys_dir, 949 DEFAULT_ARCHIVE_SUBDIR) == -1) { 950 log_err("Couldn't create default archive path '%s/%s'.", 951 cmd->sys_dir, DEFAULT_ARCHIVE_SUBDIR); 952 return 0; 953 } 954 955 dir = find_config_tree_str(cmd, "backup/archive_dir", 956 default_dir); 957 958 if (!archive_init(cmd, dir, days, min, 959 cmd->default_settings.archive)) { 960 log_debug("backup_init failed."); 961 return 0; 962 } 963 964 /* set up the backup */ 965 cmd->default_settings.backup = 966 find_config_tree_bool(cmd, "backup/backup", 967 DEFAULT_BACKUP_ENABLED); 968 969 if (dm_snprintf 970 (default_dir, sizeof(default_dir), "%s/%s", cmd->sys_dir, 971 DEFAULT_BACKUP_SUBDIR) == -1) { 972 log_err("Couldn't create default backup path '%s/%s'.", 973 cmd->sys_dir, DEFAULT_BACKUP_SUBDIR); 974 return 0; 975 } 976 977 dir = find_config_tree_str(cmd, "backup/backup_dir", default_dir); 978 979 if (!backup_init(cmd, dir, cmd->default_settings.backup)) { 980 log_debug("backup_init failed."); 981 return 0; 982 } 983 984 return 1; 985 } 986 987 static void _init_rand(struct cmd_context *cmd) 988 { 989 if (read_urandom(&cmd->rand_seed, sizeof(cmd->rand_seed))) 990 return; 991 992 cmd->rand_seed = (unsigned) time(NULL) + (unsigned) getpid(); 993 } 994 995 static void _init_globals(struct cmd_context *cmd) 996 { 997 init_full_scan_done(0); 998 init_mirror_in_sync(0); 999 1000 } 1001 1002 /* Entry point */ 1003 struct cmd_context *create_toolcontext(unsigned is_long_lived) 1004 { 1005 struct cmd_context *cmd; 1006 1007 #ifdef M_MMAP_MAX 1008 mallopt(M_MMAP_MAX, 0); 1009 #endif 1010 1011 if (!setlocale(LC_ALL, "")) 1012 log_very_verbose("setlocale failed"); 1013 1014 #ifdef INTL_PACKAGE 1015 bindtextdomain(INTL_PACKAGE, LOCALEDIR); 1016 #endif 1017 1018 init_syslog(DEFAULT_LOG_FACILITY); 1019 1020 if (!(cmd = dm_malloc(sizeof(*cmd)))) { 1021 log_error("Failed to allocate command context"); 1022 return NULL; 1023 } 1024 memset(cmd, 0, sizeof(*cmd)); 1025 cmd->is_long_lived = is_long_lived; 1026 cmd->handles_missing_pvs = 0; 1027 cmd->hosttags = 0; 1028 dm_list_init(&cmd->formats); 1029 dm_list_init(&cmd->segtypes); 1030 dm_list_init(&cmd->tags); 1031 dm_list_init(&cmd->config_files); 1032 1033 strcpy(cmd->sys_dir, DEFAULT_SYS_DIR); 1034 1035 if (!_get_env_vars(cmd)) 1036 goto error; 1037 1038 /* Create system directory if it doesn't already exist */ 1039 if (*cmd->sys_dir && !dm_create_dir(cmd->sys_dir)) { 1040 log_error("Failed to create LVM2 system dir for metadata backups, config " 1041 "files and internal cache."); 1042 log_error("Set environment variable LVM_SYSTEM_DIR to alternative location " 1043 "or empty string."); 1044 goto error; 1045 } 1046 1047 if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) { 1048 log_error("Library memory pool creation failed"); 1049 goto error; 1050 } 1051 1052 if (!_init_lvm_conf(cmd)) 1053 goto error; 1054 1055 _init_logging(cmd); 1056 1057 if (!_init_hostname(cmd)) 1058 goto error; 1059 1060 if (!_init_tags(cmd, cmd->cft)) 1061 goto error; 1062 1063 if (!_init_tag_configs(cmd)) 1064 goto error; 1065 1066 if (!_merge_config_files(cmd)) 1067 goto error; 1068 1069 if (!_process_config(cmd)) 1070 goto error; 1071 1072 if (!_init_dev_cache(cmd)) 1073 goto error; 1074 1075 if (!_init_filters(cmd, 1)) 1076 goto error; 1077 1078 if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) { 1079 log_error("Command memory pool creation failed"); 1080 goto error; 1081 } 1082 1083 memlock_init(cmd); 1084 1085 if (!_init_formats(cmd)) 1086 goto error; 1087 1088 if (!init_lvmcache_orphans(cmd)) 1089 goto error; 1090 1091 if (!_init_segtypes(cmd)) 1092 goto error; 1093 1094 if (!_init_backup(cmd)) 1095 goto error; 1096 1097 _init_rand(cmd); 1098 1099 _init_globals(cmd); 1100 1101 cmd->default_settings.cache_vgmetadata = 1; 1102 cmd->current_settings = cmd->default_settings; 1103 1104 cmd->config_valid = 1; 1105 return cmd; 1106 1107 error: 1108 dm_free(cmd); 1109 return NULL; 1110 } 1111 1112 static void _destroy_formats(struct dm_list *formats) 1113 { 1114 struct dm_list *fmtl, *tmp; 1115 struct format_type *fmt; 1116 void *lib; 1117 1118 dm_list_iterate_safe(fmtl, tmp, formats) { 1119 fmt = dm_list_item(fmtl, struct format_type); 1120 dm_list_del(&fmt->list); 1121 lib = fmt->library; 1122 fmt->ops->destroy(fmt); 1123 #ifdef HAVE_LIBDL 1124 if (lib) 1125 dlclose(lib); 1126 #endif 1127 } 1128 } 1129 1130 static void _destroy_segtypes(struct dm_list *segtypes) 1131 { 1132 struct dm_list *sgtl, *tmp; 1133 struct segment_type *segtype; 1134 void *lib; 1135 1136 dm_list_iterate_safe(sgtl, tmp, segtypes) { 1137 segtype = dm_list_item(sgtl, struct segment_type); 1138 dm_list_del(&segtype->list); 1139 lib = segtype->library; 1140 segtype->ops->destroy(segtype); 1141 #ifdef HAVE_LIBDL 1142 if (lib) 1143 dlclose(lib); 1144 #endif 1145 } 1146 } 1147 1148 int refresh_toolcontext(struct cmd_context *cmd) 1149 { 1150 log_verbose("Reloading config files"); 1151 1152 /* 1153 * Don't update the persistent filter cache as we will 1154 * perform a full rescan. 1155 */ 1156 1157 activation_release(); 1158 lvmcache_destroy(cmd, 0); 1159 label_exit(); 1160 _destroy_segtypes(&cmd->segtypes); 1161 _destroy_formats(&cmd->formats); 1162 if (cmd->filter) { 1163 cmd->filter->destroy(cmd->filter); 1164 cmd->filter = NULL; 1165 } 1166 dev_cache_exit(); 1167 _destroy_tags(cmd); 1168 _destroy_tag_configs(cmd); 1169 1170 cmd->config_valid = 0; 1171 1172 cmd->hosttags = 0; 1173 1174 if (!_init_lvm_conf(cmd)) 1175 return 0; 1176 1177 _init_logging(cmd); 1178 1179 if (!_init_tags(cmd, cmd->cft)) 1180 return 0; 1181 1182 if (!_init_tag_configs(cmd)) 1183 return 0; 1184 1185 if (!_merge_config_files(cmd)) 1186 return 0; 1187 1188 if (!_process_config(cmd)) 1189 return 0; 1190 1191 if (!_init_dev_cache(cmd)) 1192 return 0; 1193 1194 if (!_init_filters(cmd, 0)) 1195 return 0; 1196 1197 if (!_init_formats(cmd)) 1198 return 0; 1199 1200 if (!init_lvmcache_orphans(cmd)) 1201 return 0; 1202 1203 if (!_init_segtypes(cmd)) 1204 return 0; 1205 1206 /* 1207 * If we are a long-lived process, write out the updated persistent 1208 * device cache for the benefit of short-lived processes. 1209 */ 1210 if (cmd->is_long_lived && cmd->dump_filter) 1211 persistent_filter_dump(cmd->filter); 1212 1213 cmd->config_valid = 1; 1214 return 1; 1215 } 1216 1217 void destroy_toolcontext(struct cmd_context *cmd) 1218 { 1219 if (cmd->dump_filter) 1220 persistent_filter_dump(cmd->filter); 1221 1222 archive_exit(cmd); 1223 backup_exit(cmd); 1224 lvmcache_destroy(cmd, 0); 1225 label_exit(); 1226 _destroy_segtypes(&cmd->segtypes); 1227 _destroy_formats(&cmd->formats); 1228 cmd->filter->destroy(cmd->filter); 1229 dm_pool_destroy(cmd->mem); 1230 dev_cache_exit(); 1231 _destroy_tags(cmd); 1232 _destroy_tag_configs(cmd); 1233 dm_pool_destroy(cmd->libmem); 1234 dm_free(cmd); 1235 1236 release_log_memory(); 1237 activation_exit(); 1238 fin_log(); 1239 fin_syslog(); 1240 } 1241