2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
5 * This file is part of LVM2.
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
9 * of the GNU Lesser General Public License v.2.1.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 #include "toolcontext.h"
20 #include "lvm-string.h"
23 #include "filter-composite.h"
24 #include "filter-md.h"
25 #include "filter-persistent.h"
26 #include "filter-regex.h"
27 #include "filter-sysfs.h"
30 #include "format-text.h"
36 #include "dev-cache.h"
40 #include "sharedlib.h"
48 #include "format_pool.h"
53 #include <sys/utsname.h>
61 static int _get_env_vars(struct cmd_context *cmd)
65 /* Set to "" to avoid using any system directory */
66 if ((e = getenv("LVM_SYSTEM_DIR"))) {
67 if (dm_snprintf(cmd->system_dir, sizeof(cmd->system_dir),
69 log_error("LVM_SYSTEM_DIR environment variable "
78 static void _get_sysfs_dir(struct cmd_context *cmd)
80 static char proc_mounts[PATH_MAX];
81 static char *split[4], buffer[PATH_MAX + 16];
85 cmd->sysfs_dir[0] = '\0';
86 if (!*cmd->proc_dir) {
87 log_debug("No proc filesystem found: skipping sysfs detection");
91 if (dm_snprintf(proc_mounts, sizeof(proc_mounts),
92 "%s/mounts", cmd->proc_dir) < 0) {
93 log_error("Failed to create /proc/mounts string for sysfs detection");
97 if (!(fp = fopen(proc_mounts, "r"))) {
98 log_sys_error("_get_sysfs_dir: fopen %s", proc_mounts);
102 while (fgets(buffer, sizeof(buffer), fp)) {
103 if (dm_split_words(buffer, 4, 0, split) == 4 &&
104 !strcmp(split[2], "sysfs")) {
111 log_sys_error("fclose", proc_mounts);
114 log_error("Failed to find sysfs mount point");
118 strncpy(cmd->sysfs_dir, sys_mnt, sizeof(cmd->sysfs_dir));
121 static void _init_logging(struct cmd_context *cmd)
126 const char *log_file;
130 cmd->default_settings.syslog =
131 find_config_tree_int(cmd, "log/syslog", DEFAULT_SYSLOG);
132 if (cmd->default_settings.syslog != 1)
135 if (cmd->default_settings.syslog > 1)
136 init_syslog(cmd->default_settings.syslog);
138 /* Debug level for log file output */
139 cmd->default_settings.debug =
140 find_config_tree_int(cmd, "log/level", DEFAULT_LOGLEVEL);
141 init_debug(cmd->default_settings.debug);
143 /* Verbose level for tty output */
144 cmd->default_settings.verbose =
145 find_config_tree_int(cmd, "log/verbose", DEFAULT_VERBOSE);
146 init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL);
148 /* Log message formatting */
149 init_indent(find_config_tree_int(cmd, "log/indent",
151 init_abort_on_internal_errors(find_config_tree_int(cmd, "global/abort_on_internal_errors",
152 DEFAULT_ABORT_ON_INTERNAL_ERRORS));
154 cmd->default_settings.msg_prefix = find_config_tree_str(cmd,
157 init_msg_prefix(cmd->default_settings.msg_prefix);
159 cmd->default_settings.cmd_name = find_config_tree_int(cmd,
162 init_cmd_name(cmd->default_settings.cmd_name);
165 cmd->default_settings.test =
166 find_config_tree_int(cmd, "global/test", 0);
167 init_test(cmd->default_settings.test);
169 /* Settings for logging to file */
170 if (find_config_tree_int(cmd, "log/overwrite", DEFAULT_OVERWRITE))
173 log_file = find_config_tree_str(cmd, "log/file", 0);
176 release_log_memory();
178 init_log_file(log_file, append);
181 log_file = find_config_tree_str(cmd, "log/activate_file", 0);
183 init_log_direct(log_file, append);
185 init_log_while_suspended(find_config_tree_int(cmd,
186 "log/activation", 0));
189 ctime_r(&t, &timebuf[0]);
191 log_verbose("Logging initialised at %s", timebuf);
193 /* Tell device-mapper about our logging */
194 #ifdef DEVMAPPER_SUPPORT
195 dm_log_with_errno_init(print_log);
197 reset_log_duplicated();
201 static int _process_config(struct cmd_context *cmd)
204 const char *read_ahead;
206 const struct config_node *cn;
207 const struct config_value *cv;
210 cmd->default_settings.umask = find_config_tree_int(cmd,
214 if ((old_umask = umask((mode_t) cmd->default_settings.umask)) !=
215 (mode_t) cmd->default_settings.umask)
216 log_verbose("Set umask from %04o to %04o",
217 old_umask, cmd->default_settings.umask);
220 if (dm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
221 find_config_tree_str(cmd, "devices/dir",
222 DEFAULT_DEV_DIR)) < 0) {
223 log_error("Device directory given in config file too long");
226 #ifdef DEVMAPPER_SUPPORT
227 dm_set_dev_dir(cmd->dev_dir);
231 if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
232 find_config_tree_str(cmd, "global/proc",
233 DEFAULT_PROC_DIR)) < 0) {
234 log_error("Device directory given in config file too long");
238 if (*cmd->proc_dir && !dir_exists(cmd->proc_dir)) {
239 log_warn("WARNING: proc dir %s not found - some checks will be bypassed",
241 cmd->proc_dir[0] = '\0';
244 /* FIXME Use global value of sysfs_dir everywhere instead cmd->sysfs_dir. */
246 set_sysfs_dir_path(cmd->sysfs_dir);
249 cmd->default_settings.activation = find_config_tree_int(cmd,
252 set_activation(cmd->default_settings.activation);
254 cmd->default_settings.suffix = find_config_tree_int(cmd,
258 if (!(cmd->default_settings.unit_factor =
259 units_to_bytes(find_config_tree_str(cmd,
262 &cmd->default_settings.unit_type))) {
263 log_error("Invalid units specification");
267 read_ahead = find_config_tree_str(cmd, "activation/readahead", DEFAULT_READ_AHEAD);
268 if (!strcasecmp(read_ahead, "auto"))
269 cmd->default_settings.read_ahead = DM_READ_AHEAD_AUTO;
270 else if (!strcasecmp(read_ahead, "none"))
271 cmd->default_settings.read_ahead = DM_READ_AHEAD_NONE;
273 log_error("Invalid readahead specification");
277 cmd->default_settings.udev_rules = find_config_tree_int(cmd,
278 "activation/udev_rules",
281 cmd->default_settings.udev_sync = find_config_tree_int(cmd,
282 "activation/udev_sync",
285 cmd->stripe_filler = find_config_tree_str(cmd,
286 "activation/missing_stripe_filler",
287 DEFAULT_STRIPE_FILLER);
289 /* 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)? */
290 if (!strcmp(cmd->stripe_filler, "/dev/ioerror") &&
291 stat(cmd->stripe_filler, &st))
292 cmd->stripe_filler = "error";
294 if (strcmp(cmd->stripe_filler, "error")) {
295 if (stat(cmd->stripe_filler, &st)) {
296 log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
297 "is invalid,", cmd->stripe_filler);
298 log_warn(" stat failed: %s", strerror(errno));
299 log_warn("Falling back to \"error\" missing_stripe_filler.");
300 cmd->stripe_filler = "error";
301 } else if (!S_ISBLK(st.st_mode)) {
302 log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
303 "is not a block device.", cmd->stripe_filler);
304 log_warn("Falling back to \"error\" missing_stripe_filler.");
305 cmd->stripe_filler = "error";
309 cmd->si_unit_consistency = find_config_tree_int(cmd,
310 "global/si_unit_consistency",
311 DEFAULT_SI_UNIT_CONSISTENCY);
313 if ((cn = find_config_tree_node(cmd, "activation/mlock_filter")))
314 for (cv = cn->v; cv; cv = cv->next)
315 if ((cv->type != CFG_STRING) || !cv->v.str[0])
316 log_error("Ignoring invalid activation/mlock_filter entry in config file");
318 cmd->metadata_read_only = find_config_tree_int(cmd, "global/metadata_read_only",
319 DEFAULT_METADATA_READ_ONLY);
324 static int _set_tag(struct cmd_context *cmd, const char *tag)
326 log_very_verbose("Setting host tag: %s", dm_pool_strdup(cmd->libmem, tag));
328 if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
329 log_error("_set_tag: str_list_add %s failed", tag);
336 static int _check_host_filters(struct cmd_context *cmd, const struct config_node *hn,
339 const struct config_node *cn;
340 const struct config_value *cv;
344 for (cn = hn; cn; cn = cn->sib) {
347 if (!strcmp(cn->key, "host_list")) {
349 if (cn->v->type == CFG_EMPTY_ARRAY)
351 for (cv = cn->v; cv; cv = cv->next) {
352 if (cv->type != CFG_STRING) {
353 log_error("Invalid hostname string "
354 "for tag %s", cn->key);
357 if (!strcmp(cv->v.str, cmd->hostname)) {
363 if (!strcmp(cn->key, "host_filter")) {
364 log_error("host_filter not supported yet");
372 static int _init_tags(struct cmd_context *cmd, struct config_tree *cft)
374 const struct config_node *tn, *cn;
378 if (!(tn = find_config_node(cft->root, "tags")) || !tn->child)
381 /* NB hosttags 0 when already 1 intentionally does not delete the tag */
382 if (!cmd->hosttags && find_config_int(cft->root, "tags/hosttags",
384 /* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
385 if (!_set_tag(cmd, cmd->hostname))
390 for (cn = tn->child; cn; cn = cn->sib) {
396 if (!validate_name(tag)) {
397 log_error("Invalid tag in config file: %s", cn->key);
402 if (!_check_host_filters(cmd, cn->child, &passes))
407 if (!_set_tag(cmd, tag))
414 static int _load_config_file(struct cmd_context *cmd, const char *tag)
416 char config_file[PATH_MAX] = "";
417 const char *filler = "";
419 struct config_tree_list *cfl;
424 if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
425 cmd->system_dir, filler, tag) < 0) {
426 log_error("LVM_SYSTEM_DIR or tag was too long");
430 if (!(cfl = dm_pool_alloc(cmd->libmem, sizeof(*cfl)))) {
431 log_error("config_tree_list allocation failed");
435 if (!(cfl->cft = create_config_tree(config_file, 0))) {
436 log_error("config_tree allocation failed");
440 /* Is there a config file? */
441 if (stat(config_file, &info) == -1) {
442 if (errno == ENOENT) {
443 dm_list_add(&cmd->config_files, &cfl->list);
446 log_sys_error("stat", config_file);
447 destroy_config_tree(cfl->cft);
451 log_very_verbose("Loading config file: %s", config_file);
452 if (!read_config_file(cfl->cft)) {
453 log_error("Failed to load config file %s", config_file);
454 destroy_config_tree(cfl->cft);
458 dm_list_add(&cmd->config_files, &cfl->list);
462 _init_tags(cmd, cfl->cft);
464 /* Use temporary copy of lvm.conf while loading other files */
470 /* Find and read first config file */
471 static int _init_lvm_conf(struct cmd_context *cmd)
473 /* No config file if LVM_SYSTEM_DIR is empty */
474 if (!*cmd->system_dir) {
475 if (!(cmd->cft = create_config_tree(NULL, 0))) {
476 log_error("Failed to create config tree");
482 if (!_load_config_file(cmd, ""))
488 /* Read any additional config files */
489 static int _init_tag_configs(struct cmd_context *cmd)
493 /* Tag list may grow while inside this loop */
494 dm_list_iterate_items(sl, &cmd->tags) {
495 if (!_load_config_file(cmd, sl->str))
502 static int _merge_config_files(struct cmd_context *cmd)
504 struct config_tree_list *cfl;
506 /* Replace temporary duplicate copy of lvm.conf */
507 if (cmd->cft->root) {
508 if (!(cmd->cft = create_config_tree(NULL, 0))) {
509 log_error("Failed to create config tree");
514 dm_list_iterate_items(cfl, &cmd->config_files) {
515 /* Merge all config trees into cmd->cft using merge/tag rules */
516 if (!merge_config_tree(cmd, cmd->cft, cfl->cft))
523 static void _destroy_tags(struct cmd_context *cmd)
525 struct dm_list *slh, *slht;
527 dm_list_iterate_safe(slh, slht, &cmd->tags) {
532 int config_files_changed(struct cmd_context *cmd)
534 struct config_tree_list *cfl;
536 dm_list_iterate_items(cfl, &cmd->config_files) {
537 if (config_file_changed(cfl->cft))
544 static void _destroy_tag_configs(struct cmd_context *cmd)
546 struct config_tree_list *cfl;
548 dm_list_iterate_items(cfl, &cmd->config_files) {
549 if (cfl->cft == cmd->cft)
551 destroy_config_tree(cfl->cft);
555 destroy_config_tree(cmd->cft);
559 dm_list_init(&cmd->config_files);
562 static int _init_dev_cache(struct cmd_context *cmd)
564 const struct config_node *cn;
565 const struct config_value *cv;
567 init_dev_disable_after_error_count(
568 find_config_tree_int(cmd, "devices/disable_after_error_count",
569 DEFAULT_DISABLE_AFTER_ERROR_COUNT));
571 if (!dev_cache_init(cmd))
574 if (!(cn = find_config_tree_node(cmd, "devices/scan"))) {
575 if (!dev_cache_add_dir("/dev")) {
576 log_error("Failed to add /dev to internal "
580 log_verbose("device/scan not in config file: "
581 "Defaulting to /dev");
585 for (cv = cn->v; cv; cv = cv->next) {
586 if (cv->type != CFG_STRING) {
587 log_error("Invalid string in config file: "
592 if (!dev_cache_add_dir(cv->v.str)) {
593 log_error("Failed to add %s to internal device cache",
599 if (!(cn = find_config_tree_node(cmd, "devices/loopfiles")))
602 for (cv = cn->v; cv; cv = cv->next) {
603 if (cv->type != CFG_STRING) {
604 log_error("Invalid string in config file: "
605 "devices/loopfiles");
609 if (!dev_cache_add_loopfile(cv->v.str)) {
610 log_error("Failed to add loopfile %s to internal "
611 "device cache", cv->v.str);
620 #define MAX_FILTERS 4
622 static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
624 unsigned nr_filt = 0;
625 const struct config_node *cn;
626 struct dev_filter *filters[MAX_FILTERS];
628 memset(filters, 0, sizeof(filters));
631 * Filters listed in order: top one gets applied first.
632 * Failure to initialise some filters is not fatal.
633 * Update MAX_FILTERS definition above when adding new filters.
637 * sysfs filter. Only available on 2.6 kernels. Non-critical.
638 * Listed first because it's very efficient at eliminating
639 * unavailable devices.
641 if (find_config_tree_bool(cmd, "devices/sysfs_scan",
642 DEFAULT_SYSFS_SCAN)) {
643 if ((filters[nr_filt] = sysfs_filter_create(cmd->sysfs_dir)))
647 /* regex filter. Optional. */
648 if (!(cn = find_config_tree_node(cmd, "devices/filter")))
649 log_very_verbose("devices/filter not found in config file: "
650 "no regex filter installed");
652 else if (!(filters[nr_filt++] = regex_filter_create(cn->v))) {
653 log_error("Failed to create regex device filter");
657 /* device type filter. Required. */
658 cn = find_config_tree_node(cmd, "devices/types");
659 if (!(filters[nr_filt++] = lvm_type_filter_create(cmd->proc_dir, cn))) {
660 log_error("Failed to create lvm type filter");
664 /* md component filter. Optional, non-critical. */
665 if (find_config_tree_bool(cmd, "devices/md_component_detection",
666 DEFAULT_MD_COMPONENT_DETECTION)) {
667 init_md_filtering(1);
668 if ((filters[nr_filt] = md_filter_create()))
672 /* Only build a composite filter if we really need it. */
673 return (nr_filt == 1) ?
674 filters[0] : composite_filter_create(nr_filt, filters);
676 nr_filt--; /* skip NULL */
677 while (nr_filt-- > 0)
678 filters[nr_filt]->destroy(filters[nr_filt]);
682 static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
684 const char *dev_cache = NULL, *cache_dir, *cache_file_prefix;
685 struct dev_filter *f3, *f4;
687 char cache_file[PATH_MAX];
689 cmd->dump_filter = 0;
691 if (!(f3 = _init_filter_components(cmd)))
694 init_ignore_suspended_devices(find_config_tree_int(cmd,
695 "devices/ignore_suspended_devices", DEFAULT_IGNORE_SUSPENDED_DEVICES));
698 * If 'cache_dir' or 'cache_file_prefix' is set, ignore 'cache'.
700 cache_dir = find_config_tree_str(cmd, "devices/cache_dir", NULL);
701 cache_file_prefix = find_config_tree_str(cmd, "devices/cache_file_prefix", NULL);
703 if (cache_dir || cache_file_prefix) {
704 if (dm_snprintf(cache_file, sizeof(cache_file),
706 cache_dir ? "" : cmd->system_dir,
707 cache_dir ? "" : "/",
708 cache_dir ? : DEFAULT_CACHE_SUBDIR,
709 cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) {
710 log_error("Persistent cache filename too long.");
713 } else if (!(dev_cache = find_config_tree_str(cmd, "devices/cache", NULL)) &&
714 (dm_snprintf(cache_file, sizeof(cache_file),
716 cmd->system_dir, DEFAULT_CACHE_SUBDIR,
717 DEFAULT_CACHE_FILE_PREFIX) < 0)) {
718 log_error("Persistent cache filename too long.");
723 dev_cache = cache_file;
725 if (!(f4 = persistent_filter_create(f3, dev_cache))) {
726 log_error("Failed to create persistent device filter");
730 /* Should we ever dump persistent filter state? */
731 if (find_config_tree_int(cmd, "devices/write_cache_state", 1))
732 cmd->dump_filter = 1;
734 if (!*cmd->system_dir)
735 cmd->dump_filter = 0;
738 * Only load persistent filter device cache on startup if it is newer
739 * than the config file and this is not a long-lived process.
741 if (load_persistent_cache && !cmd->is_long_lived &&
742 !stat(dev_cache, &st) &&
743 (st.st_ctime > config_file_timestamp(cmd->cft)) &&
744 !persistent_filter_load(f4, NULL))
745 log_verbose("Failed to load existing device cache from %s",
753 struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format)
755 struct format_type *fmt;
757 dm_list_iterate_items(fmt, &cmd->formats)
758 if (!strcasecmp(fmt->name, format) ||
759 !strcasecmp(fmt->name + 3, format) ||
760 (fmt->alias && !strcasecmp(fmt->alias, format)))
766 static int _init_formats(struct cmd_context *cmd)
770 struct format_type *fmt;
773 const struct config_node *cn;
779 if (!(fmt = init_lvm1_format(cmd)))
782 dm_list_add(&cmd->formats, &fmt->list);
786 if (!(fmt = init_pool_format(cmd)))
789 dm_list_add(&cmd->formats, &fmt->list);
793 /* Load any formats in shared libs if not static */
795 (cn = find_config_tree_node(cmd, "global/format_libraries"))) {
797 const struct config_value *cv;
798 struct format_type *(*init_format_fn) (struct cmd_context *);
801 for (cv = cn->v; cv; cv = cv->next) {
802 if (cv->type != CFG_STRING) {
803 log_error("Invalid string in config file: "
804 "global/format_libraries");
807 if (!(lib = load_shared_library(cmd, cv->v.str,
811 if (!(init_format_fn = dlsym(lib, "init_format"))) {
812 log_error("Shared library %s does not contain "
813 "format functions", cv->v.str);
818 if (!(fmt = init_format_fn(cmd))) {
824 dm_list_add(&cmd->formats, &fmt->list);
829 if (!(fmt = create_text_format(cmd)))
832 dm_list_add(&cmd->formats, &fmt->list);
834 cmd->fmt_backup = fmt;
836 format = find_config_tree_str(cmd, "global/format",
839 dm_list_iterate_items(fmt, &cmd->formats) {
840 if (!strcasecmp(fmt->name, format) ||
841 (fmt->alias && !strcasecmp(fmt->alias, format))) {
842 cmd->default_settings.fmt_name = fmt->name;
848 log_error("_init_formats: Default format (%s) not found", format);
852 int init_lvmcache_orphans(struct cmd_context *cmd)
854 struct format_type *fmt;
856 dm_list_iterate_items(fmt, &cmd->formats)
857 if (!lvmcache_add_orphan_vginfo(fmt->orphan_vg_name, fmt))
863 struct segtype_library {
864 struct cmd_context *cmd;
869 int lvm_register_segtype(struct segtype_library *seglib,
870 struct segment_type *segtype)
872 struct segment_type *segtype2;
874 segtype->library = seglib->lib;
875 segtype->cmd = seglib->cmd;
877 dm_list_iterate_items(segtype2, &seglib->cmd->segtypes) {
878 if (strcmp(segtype2->name, segtype->name))
880 log_error("Duplicate segment type %s: "
881 "unloading shared library %s",
882 segtype->name, seglib->libname);
883 segtype->ops->destroy(segtype);
887 dm_list_add(&seglib->cmd->segtypes, &segtype->list);
892 static int _init_single_segtype(struct cmd_context *cmd,
893 struct segtype_library *seglib)
895 struct segment_type *(*init_segtype_fn) (struct cmd_context *);
896 struct segment_type *segtype;
898 if (!(init_segtype_fn = dlsym(seglib->lib, "init_segtype"))) {
899 log_error("Shared library %s does not contain segment type "
900 "functions", seglib->libname);
904 if (!(segtype = init_segtype_fn(seglib->cmd)))
907 return lvm_register_segtype(seglib, segtype);
910 static int _init_segtypes(struct cmd_context *cmd)
912 struct segment_type *segtype;
913 struct segtype_library seglib = { .cmd = cmd };
916 const struct config_node *cn;
919 if (!(segtype = init_striped_segtype(cmd)))
921 segtype->library = NULL;
922 dm_list_add(&cmd->segtypes, &segtype->list);
924 if (!(segtype = init_zero_segtype(cmd)))
926 segtype->library = NULL;
927 dm_list_add(&cmd->segtypes, &segtype->list);
929 if (!(segtype = init_error_segtype(cmd)))
931 segtype->library = NULL;
932 dm_list_add(&cmd->segtypes, &segtype->list);
934 if (!(segtype = init_free_segtype(cmd)))
936 segtype->library = NULL;
937 dm_list_add(&cmd->segtypes, &segtype->list);
939 #ifdef SNAPSHOT_INTERNAL
940 if (!(segtype = init_snapshot_segtype(cmd)))
942 segtype->library = NULL;
943 dm_list_add(&cmd->segtypes, &segtype->list);
946 #ifdef MIRRORED_INTERNAL
947 if (!(segtype = init_mirrored_segtype(cmd)))
949 segtype->library = NULL;
950 dm_list_add(&cmd->segtypes, &segtype->list);
953 #ifdef REPLICATOR_INTERNAL
954 if (!init_replicator_segtype(&seglib))
959 /* Load any formats in shared libs unless static */
961 (cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
963 const struct config_value *cv;
964 int (*init_multiple_segtypes_fn) (struct cmd_context *,
965 struct segtype_library *);
967 for (cv = cn->v; cv; cv = cv->next) {
968 if (cv->type != CFG_STRING) {
969 log_error("Invalid string in config file: "
970 "global/segment_libraries");
973 seglib.libname = cv->v.str;
974 if (!(seglib.lib = load_shared_library(cmd,
979 if ((init_multiple_segtypes_fn =
980 dlsym(seglib.lib, "init_multiple_segtypes"))) {
981 if (dlsym(seglib.lib, "init_segtype"))
982 log_warn("WARNING: Shared lib %s has "
983 "conflicting init fns. Using"
984 " init_multiple_segtypes().",
987 init_multiple_segtypes_fn =
988 _init_single_segtype;
990 if (!init_multiple_segtypes_fn(cmd, &seglib)) {
991 struct dm_list *sgtl, *tmp;
992 log_error("init_multiple_segtypes() failed: "
993 "Unloading shared library %s",
995 dm_list_iterate_safe(sgtl, tmp, &cmd->segtypes) {
996 segtype = dm_list_item(sgtl, struct segment_type);
997 if (segtype->library == seglib.lib) {
998 dm_list_del(&segtype->list);
999 segtype->ops->destroy(segtype);
1002 dlclose(seglib.lib);
1012 static int _init_hostname(struct cmd_context *cmd)
1017 log_sys_error("uname", "_init_hostname");
1021 if (!(cmd->hostname = dm_pool_strdup(cmd->libmem, uts.nodename))) {
1022 log_error("_init_hostname: dm_pool_strdup failed");
1026 if (!(cmd->kernel_vsn = dm_pool_strdup(cmd->libmem, uts.release))) {
1027 log_error("_init_hostname: dm_pool_strdup kernel_vsn failed");
1034 static int _init_backup(struct cmd_context *cmd)
1037 char default_dir[PATH_MAX];
1040 if (!cmd->system_dir[0]) {
1041 log_warn("WARNING: Metadata changes will NOT be backed up");
1042 backup_init(cmd, "", 0);
1043 archive_init(cmd, "", 0, 0, 0);
1047 /* set up archiving */
1048 cmd->default_settings.archive =
1049 find_config_tree_bool(cmd, "backup/archive",
1050 DEFAULT_ARCHIVE_ENABLED);
1052 days = (uint32_t) find_config_tree_int(cmd, "backup/retain_days",
1053 DEFAULT_ARCHIVE_DAYS);
1055 min = (uint32_t) find_config_tree_int(cmd, "backup/retain_min",
1056 DEFAULT_ARCHIVE_NUMBER);
1059 (default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
1060 DEFAULT_ARCHIVE_SUBDIR) == -1) {
1061 log_error("Couldn't create default archive path '%s/%s'.",
1062 cmd->system_dir, DEFAULT_ARCHIVE_SUBDIR);
1066 dir = find_config_tree_str(cmd, "backup/archive_dir",
1069 if (!archive_init(cmd, dir, days, min,
1070 cmd->default_settings.archive)) {
1071 log_debug("archive_init failed.");
1075 /* set up the backup */
1076 cmd->default_settings.backup =
1077 find_config_tree_bool(cmd, "backup/backup",
1078 DEFAULT_BACKUP_ENABLED);
1081 (default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
1082 DEFAULT_BACKUP_SUBDIR) == -1) {
1083 log_error("Couldn't create default backup path '%s/%s'.",
1084 cmd->system_dir, DEFAULT_BACKUP_SUBDIR);
1088 dir = find_config_tree_str(cmd, "backup/backup_dir", default_dir);
1090 if (!backup_init(cmd, dir, cmd->default_settings.backup)) {
1091 log_debug("backup_init failed.");
1098 static void _init_rand(struct cmd_context *cmd)
1100 if (read_urandom(&cmd->rand_seed, sizeof(cmd->rand_seed))) {
1105 cmd->rand_seed = (unsigned) time(NULL) + (unsigned) getpid();
1109 static void _init_globals(struct cmd_context *cmd)
1111 init_full_scan_done(0);
1112 init_mirror_in_sync(0);
1117 struct cmd_context *create_toolcontext(unsigned is_long_lived,
1118 const char *system_dir)
1120 struct cmd_context *cmd;
1123 mallopt(M_MMAP_MAX, 0);
1126 if (!setlocale(LC_ALL, ""))
1127 log_very_verbose("setlocale failed");
1130 bindtextdomain(INTL_PACKAGE, LOCALEDIR);
1133 init_syslog(DEFAULT_LOG_FACILITY);
1135 if (!(cmd = dm_zalloc(sizeof(*cmd)))) {
1136 log_error("Failed to allocate command context");
1139 cmd->is_long_lived = is_long_lived;
1140 cmd->handles_missing_pvs = 0;
1141 cmd->handles_unknown_segments = 0;
1142 cmd->independent_metadata_areas = 0;
1144 dm_list_init(&cmd->arg_value_groups);
1145 dm_list_init(&cmd->formats);
1146 dm_list_init(&cmd->segtypes);
1147 dm_list_init(&cmd->tags);
1148 dm_list_init(&cmd->config_files);
1150 /* FIXME Make this configurable? */
1154 * Environment variable LVM_SYSTEM_DIR overrides this below.
1157 strncpy(cmd->system_dir, system_dir, sizeof(cmd->system_dir) - 1);
1159 strcpy(cmd->system_dir, DEFAULT_SYS_DIR);
1161 if (!_get_env_vars(cmd))
1164 /* Create system directory if it doesn't already exist */
1165 if (*cmd->system_dir && !dm_create_dir(cmd->system_dir)) {
1166 log_error("Failed to create LVM2 system dir for metadata backups, config "
1167 "files and internal cache.");
1168 log_error("Set environment variable LVM_SYSTEM_DIR to alternative location "
1169 "or empty string.");
1173 if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) {
1174 log_error("Library memory pool creation failed");
1178 if (!_init_lvm_conf(cmd))
1183 if (!_init_hostname(cmd))
1186 if (!_init_tags(cmd, cmd->cft))
1189 if (!_init_tag_configs(cmd))
1192 if (!_merge_config_files(cmd))
1195 if (!_process_config(cmd))
1198 if (!_init_dev_cache(cmd))
1201 if (!_init_filters(cmd, 1))
1204 if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
1205 log_error("Command memory pool creation failed");
1211 if (!_init_formats(cmd))
1214 if (!init_lvmcache_orphans(cmd))
1217 if (!_init_segtypes(cmd))
1220 if (!_init_backup(cmd))
1227 cmd->default_settings.cache_vgmetadata = 1;
1228 cmd->current_settings = cmd->default_settings;
1230 cmd->config_valid = 1;
1235 static void _destroy_formats(struct cmd_context *cmd, struct dm_list *formats)
1237 struct dm_list *fmtl, *tmp;
1238 struct format_type *fmt;
1241 dm_list_iterate_safe(fmtl, tmp, formats) {
1242 fmt = dm_list_item(fmtl, struct format_type);
1243 dm_list_del(&fmt->list);
1245 fmt->ops->destroy(fmt);
1252 cmd->independent_metadata_areas = 0;
1255 static void _destroy_segtypes(struct dm_list *segtypes)
1257 struct dm_list *sgtl, *tmp;
1258 struct segment_type *segtype;
1261 dm_list_iterate_safe(sgtl, tmp, segtypes) {
1262 segtype = dm_list_item(sgtl, struct segment_type);
1263 dm_list_del(&segtype->list);
1264 lib = segtype->library;
1265 segtype->ops->destroy(segtype);
1268 * If no segtypes remain from this library, close it.
1271 struct segment_type *segtype2;
1272 dm_list_iterate_items(segtype2, segtypes)
1273 if (segtype2->library == lib)
1283 int refresh_filters(struct cmd_context *cmd)
1285 int r, saved_ignore_suspended_devices = ignore_suspended_devices();
1288 cmd->filter->destroy(cmd->filter);
1292 r = _init_filters(cmd, 0);
1295 * During repair code must not reset suspended flag.
1297 init_ignore_suspended_devices(saved_ignore_suspended_devices);
1302 int refresh_toolcontext(struct cmd_context *cmd)
1304 log_verbose("Reloading config files");
1307 * Don't update the persistent filter cache as we will
1308 * perform a full rescan.
1311 activation_release();
1312 lvmcache_destroy(cmd, 0);
1314 _destroy_segtypes(&cmd->segtypes);
1315 _destroy_formats(cmd, &cmd->formats);
1317 cmd->filter->destroy(cmd->filter);
1322 _destroy_tag_configs(cmd);
1324 cmd->config_valid = 0;
1328 if (!_init_lvm_conf(cmd))
1333 if (!_init_tags(cmd, cmd->cft))
1336 if (!_init_tag_configs(cmd))
1339 if (!_merge_config_files(cmd))
1342 if (!_process_config(cmd))
1345 if (!_init_dev_cache(cmd))
1348 if (!_init_filters(cmd, 0))
1351 if (!_init_formats(cmd))
1354 if (!init_lvmcache_orphans(cmd))
1357 if (!_init_segtypes(cmd))
1360 if (!_init_backup(cmd))
1363 cmd->config_valid = 1;
1369 void destroy_toolcontext(struct cmd_context *cmd)
1371 if (cmd->dump_filter)
1372 persistent_filter_dump(cmd->filter, 1);
1376 lvmcache_destroy(cmd, 0);
1378 _destroy_segtypes(&cmd->segtypes);
1379 _destroy_formats(cmd, &cmd->formats);
1381 cmd->filter->destroy(cmd->filter);
1383 dm_pool_destroy(cmd->mem);
1386 _destroy_tag_configs(cmd);
1388 dm_pool_destroy(cmd->libmem);
1391 release_log_memory();
1393 reset_log_duplicated();