1 /* $NetBSD: toolcontext.c,v 1.2 2008/12/22 00:56:58 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 168 /* Settings for logging to file */ 169 if (find_config_tree_int(cmd, "log/overwrite", DEFAULT_OVERWRITE)) 170 append = 0; 171 172 log_file = find_config_tree_str(cmd, "log/file", 0); 173 174 if (log_file) { 175 release_log_memory(); 176 fin_log(); 177 init_log_file(log_file, append); 178 } 179 180 log_file = find_config_tree_str(cmd, "log/activate_file", 0); 181 if (log_file) 182 init_log_direct(log_file, append); 183 184 init_log_while_suspended(find_config_tree_int(cmd, 185 "log/activation", 0)); 186 187 t = time(NULL); 188 ctime_r(&t, &timebuf[0]); 189 timebuf[24] = '\0'; 190 log_verbose("Logging initialised at %s", timebuf); 191 192 /* Tell device-mapper about our logging */ 193 #ifdef DEVMAPPER_SUPPORT 194 dm_log_init(print_log); 195 #endif 196 } 197 198 static int _process_config(struct cmd_context *cmd) 199 { 200 mode_t old_umask; 201 const char *read_ahead; 202 struct stat st; 203 204 /* umask */ 205 cmd->default_settings.umask = find_config_tree_int(cmd, 206 "global/umask", 207 DEFAULT_UMASK); 208 209 if ((old_umask = umask((mode_t) cmd->default_settings.umask)) != 210 (mode_t) cmd->default_settings.umask) 211 log_verbose("Set umask to %04o", cmd->default_settings.umask); 212 213 /* dev dir */ 214 if (dm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/", 215 find_config_tree_str(cmd, "devices/dir", 216 DEFAULT_DEV_DIR)) < 0) { 217 log_error("Device directory given in config file too long"); 218 return 0; 219 } 220 #ifdef DEVMAPPER_SUPPORT 221 dm_set_dev_dir(cmd->dev_dir); 222 #endif 223 #ifndef __NetBSD__ 224 225 226 /* proc dir */ 227 if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s", 228 find_config_tree_str(cmd, "global/proc", 229 DEFAULT_PROC_DIR)) < 0) { 230 log_error("Device directory given in config file too long"); 231 return 0; 232 } 233 #endif 234 if (*cmd->proc_dir && !dir_exists(cmd->proc_dir)) { 235 log_error("WARNING: proc dir %s not found - some checks will be bypassed", 236 cmd->proc_dir); 237 *cmd->proc_dir = '\0'; 238 } 239 240 _get_sysfs_dir(cmd); 241 242 /* activation? */ 243 cmd->default_settings.activation = find_config_tree_int(cmd, 244 "global/activation", 245 DEFAULT_ACTIVATION); 246 set_activation(cmd->default_settings.activation); 247 248 cmd->default_settings.suffix = find_config_tree_int(cmd, 249 "global/suffix", 250 DEFAULT_SUFFIX); 251 252 if (!(cmd->default_settings.unit_factor = 253 units_to_bytes(find_config_tree_str(cmd, 254 "global/units", 255 DEFAULT_UNITS), 256 &cmd->default_settings.unit_type))) { 257 log_error("Invalid units specification"); 258 return 0; 259 } 260 261 read_ahead = find_config_tree_str(cmd, "activation/readahead", DEFAULT_READ_AHEAD); 262 if (!strcasecmp(read_ahead, "auto")) 263 cmd->default_settings.read_ahead = DM_READ_AHEAD_AUTO; 264 else if (!strcasecmp(read_ahead, "none")) 265 cmd->default_settings.read_ahead = DM_READ_AHEAD_NONE; 266 else { 267 log_error("Invalid readahead specification"); 268 return 0; 269 } 270 271 cmd->stripe_filler = find_config_tree_str(cmd, 272 "activation/missing_stripe_filler", 273 DEFAULT_STRIPE_FILLER); 274 275 /* 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)? */ 276 if (!strcmp(cmd->stripe_filler, "/dev/ioerror") && 277 stat(cmd->stripe_filler, &st)) 278 cmd->stripe_filler = "error"; 279 280 if (strcmp(cmd->stripe_filler, "error")) { 281 if (stat(cmd->stripe_filler, &st)) { 282 log_warn("WARNING: activation/missing_stripe_filler = \"%s\" " 283 "is invalid,", cmd->stripe_filler); 284 log_warn(" stat failed: %s", strerror(errno)); 285 log_warn("Falling back to \"error\" missing_stripe_filler."); 286 cmd->stripe_filler = "error"; 287 } else if (!S_ISBLK(st.st_mode)) { 288 log_warn("WARNING: activation/missing_stripe_filler = \"%s\" " 289 "is not a block device.", cmd->stripe_filler); 290 log_warn("Falling back to \"error\" missing_stripe_filler."); 291 cmd->stripe_filler = "error"; 292 } 293 } 294 295 return 1; 296 } 297 298 static int _set_tag(struct cmd_context *cmd, const char *tag) 299 { 300 log_very_verbose("Setting host tag: %s", dm_pool_strdup(cmd->libmem, tag)); 301 302 if (!str_list_add(cmd->libmem, &cmd->tags, tag)) { 303 log_error("_set_tag: str_list_add %s failed", tag); 304 return 0; 305 } 306 307 return 1; 308 } 309 310 static int _check_host_filters(struct cmd_context *cmd, struct config_node *hn, 311 int *passes) 312 { 313 struct config_node *cn; 314 struct config_value *cv; 315 316 *passes = 1; 317 318 for (cn = hn; cn; cn = cn->sib) { 319 if (!cn->v) 320 continue; 321 if (!strcmp(cn->key, "host_list")) { 322 *passes = 0; 323 if (cn->v->type == CFG_EMPTY_ARRAY) 324 continue; 325 for (cv = cn->v; cv; cv = cv->next) { 326 if (cv->type != CFG_STRING) { 327 log_error("Invalid hostname string " 328 "for tag %s", cn->key); 329 return 0; 330 } 331 if (!strcmp(cv->v.str, cmd->hostname)) { 332 *passes = 1; 333 return 1; 334 } 335 } 336 } 337 if (!strcmp(cn->key, "host_filter")) { 338 log_error("host_filter not supported yet"); 339 return 0; 340 } 341 } 342 343 return 1; 344 } 345 346 static int _init_tags(struct cmd_context *cmd, struct config_tree *cft) 347 { 348 const struct config_node *tn, *cn; 349 const char *tag; 350 int passes; 351 352 if (!(tn = find_config_node(cft->root, "tags")) || !tn->child) 353 return 1; 354 355 /* NB hosttags 0 when already 1 intentionally does not delete the tag */ 356 if (!cmd->hosttags && find_config_int(cft->root, "tags/hosttags", 357 DEFAULT_HOSTTAGS)) { 358 /* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */ 359 if (!_set_tag(cmd, cmd->hostname)) 360 return_0; 361 cmd->hosttags = 1; 362 } 363 364 for (cn = tn->child; cn; cn = cn->sib) { 365 if (cn->v) 366 continue; 367 tag = cn->key; 368 if (*tag == '@') 369 tag++; 370 if (!validate_name(tag)) { 371 log_error("Invalid tag in config file: %s", cn->key); 372 return 0; 373 } 374 if (cn->child) { 375 passes = 0; 376 if (!_check_host_filters(cmd, cn->child, &passes)) 377 return_0; 378 if (!passes) 379 continue; 380 } 381 if (!_set_tag(cmd, tag)) 382 return_0; 383 } 384 385 return 1; 386 } 387 388 static int _load_config_file(struct cmd_context *cmd, const char *tag) 389 { 390 char config_file[PATH_MAX] = ""; 391 const char *filler = ""; 392 struct stat info; 393 struct config_tree_list *cfl; 394 395 if (*tag) 396 filler = "_"; 397 398 if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf", 399 cmd->sys_dir, filler, tag) < 0) { 400 log_error("LVM_SYSTEM_DIR or tag was too long"); 401 return 0; 402 } 403 404 if (!(cfl = dm_pool_alloc(cmd->libmem, sizeof(*cfl)))) { 405 log_error("config_tree_list allocation failed"); 406 return 0; 407 } 408 409 if (!(cfl->cft = create_config_tree(config_file, 0))) { 410 log_error("config_tree allocation failed"); 411 return 0; 412 } 413 414 /* Is there a config file? */ 415 if (stat(config_file, &info) == -1) { 416 if (errno == ENOENT) { 417 dm_list_add(&cmd->config_files, &cfl->list); 418 goto out; 419 } 420 log_sys_error("stat", config_file); 421 destroy_config_tree(cfl->cft); 422 return 0; 423 } 424 425 log_very_verbose("Loading config file: %s", config_file); 426 if (!read_config_file(cfl->cft)) { 427 log_error("Failed to load config file %s", config_file); 428 destroy_config_tree(cfl->cft); 429 return 0; 430 } 431 432 dm_list_add(&cmd->config_files, &cfl->list); 433 434 out: 435 if (*tag) 436 _init_tags(cmd, cfl->cft); 437 else 438 /* Use temporary copy of lvm.conf while loading other files */ 439 cmd->cft = cfl->cft; 440 441 return 1; 442 } 443 444 /* Find and read first config file */ 445 static int _init_lvm_conf(struct cmd_context *cmd) 446 { 447 /* No config file if LVM_SYSTEM_DIR is empty */ 448 if (!*cmd->sys_dir) { 449 if (!(cmd->cft = create_config_tree(NULL, 0))) { 450 log_error("Failed to create config tree"); 451 return 0; 452 } 453 return 1; 454 } 455 456 if (!_load_config_file(cmd, "")) 457 return_0; 458 459 return 1; 460 } 461 462 /* Read any additional config files */ 463 static int _init_tag_configs(struct cmd_context *cmd) 464 { 465 struct str_list *sl; 466 467 /* Tag list may grow while inside this loop */ 468 dm_list_iterate_items(sl, &cmd->tags) { 469 if (!_load_config_file(cmd, sl->str)) 470 return_0; 471 } 472 473 return 1; 474 } 475 476 static int _merge_config_files(struct cmd_context *cmd) 477 { 478 struct config_tree_list *cfl; 479 480 /* Replace temporary duplicate copy of lvm.conf */ 481 if (cmd->cft->root) { 482 if (!(cmd->cft = create_config_tree(NULL, 0))) { 483 log_error("Failed to create config tree"); 484 return 0; 485 } 486 } 487 488 dm_list_iterate_items(cfl, &cmd->config_files) { 489 /* Merge all config trees into cmd->cft using merge/tag rules */ 490 if (!merge_config_tree(cmd, cmd->cft, cfl->cft)) 491 return_0; 492 } 493 494 return 1; 495 } 496 497 static void _destroy_tags(struct cmd_context *cmd) 498 { 499 struct dm_list *slh, *slht; 500 501 dm_list_iterate_safe(slh, slht, &cmd->tags) { 502 dm_list_del(slh); 503 } 504 } 505 506 int config_files_changed(struct cmd_context *cmd) 507 { 508 struct config_tree_list *cfl; 509 510 dm_list_iterate_items(cfl, &cmd->config_files) { 511 if (config_file_changed(cfl->cft)) 512 return 1; 513 } 514 515 return 0; 516 } 517 518 static void _destroy_tag_configs(struct cmd_context *cmd) 519 { 520 struct config_tree_list *cfl; 521 522 if (cmd->cft && cmd->cft->root) { 523 destroy_config_tree(cmd->cft); 524 cmd->cft = NULL; 525 } 526 527 dm_list_iterate_items(cfl, &cmd->config_files) { 528 destroy_config_tree(cfl->cft); 529 } 530 531 dm_list_init(&cmd->config_files); 532 } 533 534 static int _init_dev_cache(struct cmd_context *cmd) 535 { 536 const struct config_node *cn; 537 struct config_value *cv; 538 539 if (!dev_cache_init(cmd)) 540 return_0; 541 542 if (!(cn = find_config_tree_node(cmd, "devices/scan"))) { 543 if (!dev_cache_add_dir("/dev")) { 544 log_error("Failed to add /dev to internal " 545 "device cache"); 546 return 0; 547 } 548 log_verbose("device/scan not in config file: " 549 "Defaulting to /dev"); 550 return 1; 551 } 552 553 for (cv = cn->v; cv; cv = cv->next) { 554 if (cv->type != CFG_STRING) { 555 log_error("Invalid string in config file: " 556 "devices/scan"); 557 return 0; 558 } 559 560 if (!dev_cache_add_dir(cv->v.str)) { 561 log_error("Failed to add %s to internal device cache", 562 cv->v.str); 563 return 0; 564 } 565 } 566 567 if (!(cn = find_config_tree_node(cmd, "devices/loopfiles"))) 568 return 1; 569 570 for (cv = cn->v; cv; cv = cv->next) { 571 if (cv->type != CFG_STRING) { 572 log_error("Invalid string in config file: " 573 "devices/loopfiles"); 574 return 0; 575 } 576 577 if (!dev_cache_add_loopfile(cv->v.str)) { 578 log_error("Failed to add loopfile %s to internal " 579 "device cache", cv->v.str); 580 return 0; 581 } 582 } 583 584 585 return 1; 586 } 587 588 #define MAX_FILTERS 4 589 590 static struct dev_filter *_init_filter_components(struct cmd_context *cmd) 591 { 592 unsigned nr_filt = 0; 593 const struct config_node *cn; 594 struct dev_filter *filters[MAX_FILTERS]; 595 596 memset(filters, 0, sizeof(filters)); 597 598 /* 599 * Filters listed in order: top one gets applied first. 600 * Failure to initialise some filters is not fatal. 601 * Update MAX_FILTERS definition above when adding new filters. 602 */ 603 604 /* 605 * sysfs filter. Only available on 2.6 kernels. Non-critical. 606 * Listed first because it's very efficient at eliminating 607 * unavailable devices. 608 */ 609 if (find_config_tree_bool(cmd, "devices/sysfs_scan", 610 DEFAULT_SYSFS_SCAN)) { 611 if ((filters[nr_filt] = sysfs_filter_create(cmd->sysfs_dir))) 612 nr_filt++; 613 } 614 615 /* regex filter. Optional. */ 616 if (!(cn = find_config_tree_node(cmd, "devices/filter"))) 617 log_very_verbose("devices/filter not found in config file: " 618 "no regex filter installed"); 619 620 else if (!(filters[nr_filt++] = regex_filter_create(cn->v))) { 621 log_error("Failed to create regex device filter"); 622 return NULL; 623 } 624 625 /* device type filter. Required. */ 626 cn = find_config_tree_node(cmd, "devices/types"); 627 if (!(filters[nr_filt++] = lvm_type_filter_create(cmd->proc_dir, cn))) { 628 log_error("Failed to create lvm type filter"); 629 return NULL; 630 } 631 632 /* md component filter. Optional, non-critical. */ 633 if (find_config_tree_bool(cmd, "devices/md_component_detection", 634 DEFAULT_MD_COMPONENT_DETECTION)) { 635 init_md_filtering(1); 636 if ((filters[nr_filt] = md_filter_create())) 637 nr_filt++; 638 } 639 640 /* Only build a composite filter if we really need it. */ 641 return (nr_filt == 1) ? 642 filters[0] : composite_filter_create(nr_filt, filters); 643 } 644 645 static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache) 646 { 647 const char *dev_cache = NULL, *cache_dir, *cache_file_prefix; 648 struct dev_filter *f3, *f4; 649 struct stat st; 650 char cache_file[PATH_MAX]; 651 652 cmd->dump_filter = 0; 653 654 if (!(f3 = _init_filter_components(cmd))) 655 return 0; 656 657 init_ignore_suspended_devices(find_config_tree_int(cmd, 658 "devices/ignore_suspended_devices", DEFAULT_IGNORE_SUSPENDED_DEVICES)); 659 660 /* 661 * If 'cache_dir' or 'cache_file_prefix' is set, ignore 'cache'. 662 */ 663 cache_dir = find_config_tree_str(cmd, "devices/cache_dir", NULL); 664 cache_file_prefix = find_config_tree_str(cmd, "devices/cache_file_prefix", NULL); 665 666 if (cache_dir || cache_file_prefix) { 667 if (dm_snprintf(cache_file, sizeof(cache_file), 668 "%s%s%s/%s.cache", 669 cache_dir ? "" : cmd->sys_dir, 670 cache_dir ? "" : "/", 671 cache_dir ? : DEFAULT_CACHE_SUBDIR, 672 cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) { 673 log_error("Persistent cache filename too long."); 674 return 0; 675 } 676 } else if (!(dev_cache = find_config_tree_str(cmd, "devices/cache", NULL)) && 677 (dm_snprintf(cache_file, sizeof(cache_file), 678 "%s/%s/%s.cache", 679 cmd->sys_dir, DEFAULT_CACHE_SUBDIR, 680 DEFAULT_CACHE_FILE_PREFIX) < 0)) { 681 log_error("Persistent cache filename too long."); 682 return 0; 683 } 684 685 if (!dev_cache) 686 dev_cache = cache_file; 687 688 if (!(f4 = persistent_filter_create(f3, dev_cache))) { 689 log_error("Failed to create persistent device filter"); 690 return 0; 691 } 692 693 /* Should we ever dump persistent filter state? */ 694 if (find_config_tree_int(cmd, "devices/write_cache_state", 1)) 695 cmd->dump_filter = 1; 696 697 if (!*cmd->sys_dir) 698 cmd->dump_filter = 0; 699 700 /* 701 * Only load persistent filter device cache on startup if it is newer 702 * than the config file and this is not a long-lived process. 703 */ 704 if (load_persistent_cache && !cmd->is_long_lived && 705 !stat(dev_cache, &st) && 706 (st.st_ctime > config_file_timestamp(cmd->cft)) && 707 !persistent_filter_load(f4, NULL)) 708 log_verbose("Failed to load existing device cache from %s", 709 dev_cache); 710 711 cmd->filter = f4; 712 713 return 1; 714 } 715 716 static int _init_formats(struct cmd_context *cmd) 717 { 718 const char *format; 719 720 struct format_type *fmt; 721 722 #ifdef HAVE_LIBDL 723 const struct config_node *cn; 724 #endif 725 726 label_init(); 727 728 #ifdef LVM1_INTERNAL 729 if (!(fmt = init_lvm1_format(cmd))) 730 return 0; 731 fmt->library = NULL; 732 dm_list_add(&cmd->formats, &fmt->list); 733 #endif 734 735 #ifdef POOL_INTERNAL 736 if (!(fmt = init_pool_format(cmd))) 737 return 0; 738 fmt->library = NULL; 739 dm_list_add(&cmd->formats, &fmt->list); 740 #endif 741 742 #ifdef HAVE_LIBDL 743 /* Load any formats in shared libs if not static */ 744 if (!cmd->is_static && 745 (cn = find_config_tree_node(cmd, "global/format_libraries"))) { 746 747 struct config_value *cv; 748 struct format_type *(*init_format_fn) (struct cmd_context *); 749 void *lib; 750 751 for (cv = cn->v; cv; cv = cv->next) { 752 if (cv->type != CFG_STRING) { 753 log_error("Invalid string in config file: " 754 "global/format_libraries"); 755 return 0; 756 } 757 if (!(lib = load_shared_library(cmd, cv->v.str, 758 "format", 0))) 759 return_0; 760 761 if (!(init_format_fn = dlsym(lib, "init_format"))) { 762 log_error("Shared library %s does not contain " 763 "format functions", cv->v.str); 764 dlclose(lib); 765 return 0; 766 } 767 768 if (!(fmt = init_format_fn(cmd))) 769 return 0; 770 fmt->library = lib; 771 dm_list_add(&cmd->formats, &fmt->list); 772 } 773 } 774 #endif 775 776 if (!(fmt = create_text_format(cmd))) 777 return 0; 778 fmt->library = NULL; 779 dm_list_add(&cmd->formats, &fmt->list); 780 781 cmd->fmt_backup = fmt; 782 783 format = find_config_tree_str(cmd, "global/format", 784 DEFAULT_FORMAT); 785 786 dm_list_iterate_items(fmt, &cmd->formats) { 787 if (!strcasecmp(fmt->name, format) || 788 (fmt->alias && !strcasecmp(fmt->alias, format))) { 789 cmd->default_settings.fmt = 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 (!cmd->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, ""); 932 archive_init(cmd, "", 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 log_debug("backup_init failed."); 960 return 0; 961 } 962 963 /* set up the backup */ 964 cmd->default_settings.backup = 965 find_config_tree_bool(cmd, "backup/backup", 966 DEFAULT_BACKUP_ENABLED); 967 968 if (dm_snprintf 969 (default_dir, sizeof(default_dir), "%s/%s", cmd->sys_dir, 970 DEFAULT_BACKUP_SUBDIR) == -1) { 971 log_err("Couldn't create default backup path '%s/%s'.", 972 cmd->sys_dir, DEFAULT_BACKUP_SUBDIR); 973 return 0; 974 } 975 976 dir = find_config_tree_str(cmd, "backup/backup_dir", default_dir); 977 978 if (!backup_init(cmd, dir)) { 979 log_debug("backup_init failed."); 980 return 0; 981 } 982 983 return 1; 984 } 985 986 /* Entry point */ 987 struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static, 988 unsigned is_long_lived) 989 { 990 struct cmd_context *cmd; 991 992 #ifdef M_MMAP_MAX 993 mallopt(M_MMAP_MAX, 0); 994 #endif 995 996 if (!setlocale(LC_ALL, "")) 997 log_very_verbose("setlocale failed"); 998 999 #ifdef INTL_PACKAGE 1000 bindtextdomain(INTL_PACKAGE, LOCALEDIR); 1001 #endif 1002 1003 init_syslog(DEFAULT_LOG_FACILITY); 1004 1005 if (!(cmd = dm_malloc(sizeof(*cmd)))) { 1006 log_error("Failed to allocate command context"); 1007 return NULL; 1008 } 1009 memset(cmd, 0, sizeof(*cmd)); 1010 cmd->args = the_args; 1011 cmd->is_static = is_static; 1012 cmd->is_long_lived = is_long_lived; 1013 cmd->handles_missing_pvs = 0; 1014 cmd->hosttags = 0; 1015 dm_list_init(&cmd->formats); 1016 dm_list_init(&cmd->segtypes); 1017 dm_list_init(&cmd->tags); 1018 dm_list_init(&cmd->config_files); 1019 1020 strcpy(cmd->sys_dir, DEFAULT_SYS_DIR); 1021 1022 if (!_get_env_vars(cmd)) 1023 goto error; 1024 1025 /* Create system directory if it doesn't already exist */ 1026 if (*cmd->sys_dir && !dm_create_dir(cmd->sys_dir)) { 1027 log_error("Failed to create LVM2 system dir for metadata backups, config " 1028 "files and internal cache."); 1029 log_error("Set environment variable LVM_SYSTEM_DIR to alternative location " 1030 "or empty string."); 1031 goto error; 1032 } 1033 1034 if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) { 1035 log_error("Library memory pool creation failed"); 1036 goto error; 1037 } 1038 1039 if (!_init_lvm_conf(cmd)) 1040 goto error; 1041 1042 _init_logging(cmd); 1043 1044 if (!_init_hostname(cmd)) 1045 goto error; 1046 1047 if (!_init_tags(cmd, cmd->cft)) 1048 goto error; 1049 1050 if (!_init_tag_configs(cmd)) 1051 goto error; 1052 1053 if (!_merge_config_files(cmd)) 1054 goto error; 1055 1056 if (!_process_config(cmd)) 1057 goto error; 1058 1059 if (!_init_dev_cache(cmd)) 1060 goto error; 1061 1062 if (!_init_filters(cmd, 1)) 1063 goto error; 1064 1065 if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) { 1066 log_error("Command memory pool creation failed"); 1067 goto error; 1068 } 1069 1070 memlock_init(cmd); 1071 1072 if (!_init_formats(cmd)) 1073 goto error; 1074 1075 if (!init_lvmcache_orphans(cmd)) 1076 goto error; 1077 1078 if (!_init_segtypes(cmd)) 1079 goto error; 1080 1081 if (!_init_backup(cmd)) 1082 goto error; 1083 1084 cmd->default_settings.cache_vgmetadata = 1; 1085 cmd->current_settings = cmd->default_settings; 1086 1087 cmd->config_valid = 1; 1088 return cmd; 1089 1090 error: 1091 dm_free(cmd); 1092 return NULL; 1093 } 1094 1095 static void _destroy_formats(struct dm_list *formats) 1096 { 1097 struct dm_list *fmtl, *tmp; 1098 struct format_type *fmt; 1099 void *lib; 1100 1101 dm_list_iterate_safe(fmtl, tmp, formats) { 1102 fmt = dm_list_item(fmtl, struct format_type); 1103 dm_list_del(&fmt->list); 1104 lib = fmt->library; 1105 fmt->ops->destroy(fmt); 1106 #ifdef HAVE_LIBDL 1107 if (lib) 1108 dlclose(lib); 1109 #endif 1110 } 1111 } 1112 1113 static void _destroy_segtypes(struct dm_list *segtypes) 1114 { 1115 struct dm_list *sgtl, *tmp; 1116 struct segment_type *segtype; 1117 void *lib; 1118 1119 dm_list_iterate_safe(sgtl, tmp, segtypes) { 1120 segtype = dm_list_item(sgtl, struct segment_type); 1121 dm_list_del(&segtype->list); 1122 lib = segtype->library; 1123 segtype->ops->destroy(segtype); 1124 #ifdef HAVE_LIBDL 1125 if (lib) 1126 dlclose(lib); 1127 #endif 1128 } 1129 } 1130 1131 int refresh_toolcontext(struct cmd_context *cmd) 1132 { 1133 log_verbose("Reloading config files"); 1134 1135 /* 1136 * Don't update the persistent filter cache as we will 1137 * perform a full rescan. 1138 */ 1139 1140 activation_release(); 1141 lvmcache_destroy(cmd, 0); 1142 label_exit(); 1143 _destroy_segtypes(&cmd->segtypes); 1144 _destroy_formats(&cmd->formats); 1145 if (cmd->filter) { 1146 cmd->filter->destroy(cmd->filter); 1147 cmd->filter = NULL; 1148 } 1149 dev_cache_exit(); 1150 _destroy_tags(cmd); 1151 _destroy_tag_configs(cmd); 1152 1153 cmd->config_valid = 0; 1154 1155 cmd->hosttags = 0; 1156 1157 if (!_init_lvm_conf(cmd)) 1158 return 0; 1159 1160 _init_logging(cmd); 1161 1162 if (!_init_tags(cmd, cmd->cft)) 1163 return 0; 1164 1165 if (!_init_tag_configs(cmd)) 1166 return 0; 1167 1168 if (!_merge_config_files(cmd)) 1169 return 0; 1170 1171 if (!_process_config(cmd)) 1172 return 0; 1173 1174 if (!_init_dev_cache(cmd)) 1175 return 0; 1176 1177 if (!_init_filters(cmd, 0)) 1178 return 0; 1179 1180 if (!_init_formats(cmd)) 1181 return 0; 1182 1183 if (!init_lvmcache_orphans(cmd)) 1184 return 0; 1185 1186 if (!_init_segtypes(cmd)) 1187 return 0; 1188 1189 /* 1190 * If we are a long-lived process, write out the updated persistent 1191 * device cache for the benefit of short-lived processes. 1192 */ 1193 if (cmd->is_long_lived && cmd->dump_filter) 1194 persistent_filter_dump(cmd->filter); 1195 1196 cmd->config_valid = 1; 1197 return 1; 1198 } 1199 1200 void destroy_toolcontext(struct cmd_context *cmd) 1201 { 1202 if (cmd->dump_filter) 1203 persistent_filter_dump(cmd->filter); 1204 1205 archive_exit(cmd); 1206 backup_exit(cmd); 1207 lvmcache_destroy(cmd, 0); 1208 label_exit(); 1209 _destroy_segtypes(&cmd->segtypes); 1210 _destroy_formats(&cmd->formats); 1211 cmd->filter->destroy(cmd->filter); 1212 dm_pool_destroy(cmd->mem); 1213 dev_cache_exit(); 1214 _destroy_tags(cmd); 1215 _destroy_tag_configs(cmd); 1216 dm_pool_destroy(cmd->libmem); 1217 dm_free(cmd); 1218 1219 release_log_memory(); 1220 activation_exit(); 1221 fin_log(); 1222 fin_syslog(); 1223 } 1224