/*
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
 *
 * This file is part of LVM2.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "lib.h"
#include "toolcontext.h"
#include "metadata.h"
#include "defaults.h"
#include "lvm-string.h"
#include "activate.h"
#include "filter.h"
#include "label.h"
#include "lvm-file.h"
#include "format-text.h"
#include "display.h"
#include "memlock.h"
#include "str_list.h"
#include "segtype.h"
#include "lvmcache.h"
#include "lvmetad.h"
#include "archiver.h"
#include "lvmpolld-client.h"

#ifdef HAVE_LIBDL
#include "sharedlib.h"
#endif

#ifdef LVM1_INTERNAL
#include "format1.h"
#endif

#ifdef POOL_INTERNAL
#include "format_pool.h"
#endif

#include <locale.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <syslog.h>
#include <time.h>

#ifdef __linux__
#  include <malloc.h>
#endif

static const size_t linebuffer_size = 4096;

/*
 * Copy the input string, removing invalid characters.
 */
const char *system_id_from_string(struct cmd_context *cmd, const char *str)
{
	char *system_id;

	if (!str || !*str) {
		log_warn("WARNING: Empty system ID supplied.");
		return "";
	}

	if (!(system_id = dm_pool_zalloc(cmd->libmem, strlen(str) + 1))) {
		log_warn("WARNING: Failed to allocate system ID.");
		return NULL;
	}

	copy_systemid_chars(str, system_id);

	if (!*system_id) {
		log_warn("WARNING: Invalid system ID format: %s", str);
		return NULL;
	}

	if (!strncmp(system_id, "localhost", 9)) {
		log_warn("WARNING: system ID may not begin with the string \"localhost\".");
		return NULL;
	}

	return system_id;
}

static const char *_read_system_id_from_file(struct cmd_context *cmd, const char *file)
{
	char *line = NULL;
	size_t line_size;
	char *start, *end;
	const char *system_id = NULL;
	FILE *fp;

	if (!file || !strlen(file) || !file[0])
		return_NULL;

	if (!(fp = fopen(file, "r"))) {
		log_warn("WARNING: %s: fopen failed: %s", file, strerror(errno));
		return NULL;
	}

	while (getline(&line, &line_size, fp) > 0) {
		start = line;

		/* Ignore leading whitespace */
		while (*start && isspace(*start))
			start++;

		/* Ignore rest of line after # */
		if (!*start || *start == '#')
			continue;

		if (system_id && *system_id) {
			log_warn("WARNING: Ignoring extra line(s) in system ID file %s.", file);
			break;
		}

		/* Remove any comments from end of line */
		for (end = start; *end; end++)
			if (*end == '#') {
				*end = '\0';
				break;
			}

		system_id = system_id_from_string(cmd, start);
	}

	free(line);

	if (fclose(fp))
		stack;

	return system_id;
}

static const char *_system_id_from_source(struct cmd_context *cmd, const char *source)
{
	char filebuf[PATH_MAX];
	const char *file;
	const char *etc_str;
	const char *str;
	const char *system_id = NULL;

	if (!strcasecmp(source, "uname")) {
		if (cmd->hostname)
			system_id = system_id_from_string(cmd, cmd->hostname);
		goto out;
	}

	/* lvm.conf and lvmlocal.conf are merged into one config tree */
	if (!strcasecmp(source, "lvmlocal")) {
		if ((str = find_config_tree_str(cmd, local_system_id_CFG, NULL)))
			system_id = system_id_from_string(cmd, str);
		goto out;
	}

	if (!strcasecmp(source, "machineid") || !strcasecmp(source, "machine-id")) {
		etc_str = find_config_tree_str(cmd, global_etc_CFG, NULL);
		if (dm_snprintf(filebuf, sizeof(filebuf), "%s/machine-id", etc_str) != -1)
			system_id = _read_system_id_from_file(cmd, filebuf);
		goto out;
	}

	if (!strcasecmp(source, "file")) {
		file = find_config_tree_str(cmd, global_system_id_file_CFG, NULL);
		system_id = _read_system_id_from_file(cmd, file);
		goto out;
	}

	log_warn("WARNING: Unrecognised system_id_source \"%s\".", source);

out:
	return system_id;
}

static int _get_env_vars(struct cmd_context *cmd)
{
	const char *e;

	/* Set to "" to avoid using any system directory */
	if ((e = getenv("LVM_SYSTEM_DIR"))) {
		if (dm_snprintf(cmd->system_dir, sizeof(cmd->system_dir),
				 "%s", e) < 0) {
			log_error("LVM_SYSTEM_DIR environment variable "
				  "is too long.");
			return 0;
		}
	}

	return 1;
}

static void _get_sysfs_dir(struct cmd_context *cmd, char *buf, size_t buf_size)
{
	static char proc_mounts[PATH_MAX];
	static char *split[4], buffer[PATH_MAX + 16];
	FILE *fp;
	char *sys_mnt = NULL;

	*buf = '\0';

	if (!*cmd->proc_dir) {
		log_debug("No proc filesystem found: skipping sysfs detection");
		return;
	}

	if (dm_snprintf(proc_mounts, sizeof(proc_mounts),
			 "%s/mounts", cmd->proc_dir) < 0) {
		log_error("Failed to create /proc/mounts string for sysfs detection");
		return;
	}

	if (!(fp = fopen(proc_mounts, "r"))) {
		log_sys_error("_get_sysfs_dir fopen", proc_mounts);
		return;
	}

	while (fgets(buffer, sizeof(buffer), fp)) {
		if (dm_split_words(buffer, 4, 0, split) == 4 &&
		    !strcmp(split[2], "sysfs")) {
			sys_mnt = split[1];
			break;
		}
	}

	if (fclose(fp))
		log_sys_error("fclose", proc_mounts);

	if (!sys_mnt) {
		log_error("Failed to find sysfs mount point");
		return;
	}

	strncpy(buf, sys_mnt, buf_size);
}

static int _parse_debug_classes(struct cmd_context *cmd)
{
	const struct dm_config_node *cn;
	const struct dm_config_value *cv;
	int debug_classes = 0;

	if (!(cn = find_config_tree_array(cmd, log_debug_classes_CFG, NULL))) {
		log_error(INTERNAL_ERROR "Unable to find configuration for log/debug_classes.");
		return -1;
	}

	for (cv = cn->v; cv; cv = cv->next) {
		if (cv->type != DM_CFG_STRING) {
			log_verbose("log/debug_classes contains a value "
				    "which is not a string.  Ignoring.");
			continue;
		}

		if (!strcasecmp(cv->v.str, "all"))
			return -1;

		if (!strcasecmp(cv->v.str, "memory"))
			debug_classes |= LOG_CLASS_MEM;
		else if (!strcasecmp(cv->v.str, "devices"))
			debug_classes |= LOG_CLASS_DEVS;
		else if (!strcasecmp(cv->v.str, "activation"))
			debug_classes |= LOG_CLASS_ACTIVATION;
		else if (!strcasecmp(cv->v.str, "allocation"))
			debug_classes |= LOG_CLASS_ALLOC;
		else if (!strcasecmp(cv->v.str, "lvmetad"))
			debug_classes |= LOG_CLASS_LVMETAD;
		else if (!strcasecmp(cv->v.str, "metadata"))
			debug_classes |= LOG_CLASS_METADATA;
		else if (!strcasecmp(cv->v.str, "cache"))
			debug_classes |= LOG_CLASS_CACHE;
		else if (!strcasecmp(cv->v.str, "locking"))
			debug_classes |= LOG_CLASS_LOCKING;
		else if (!strcasecmp(cv->v.str, "lvmpolld"))
			debug_classes |= LOG_CLASS_LVMPOLLD;
		else if (!strcasecmp(cv->v.str, "dbus"))
			debug_classes |= LOG_CLASS_DBUS;
		else
			log_verbose("Unrecognised value for log/debug_classes: %s", cv->v.str);
	}

	return debug_classes;
}

static void _init_logging(struct cmd_context *cmd)
{
	int append = 1;
	time_t t;

	const char *log_file;
	char timebuf[26];

	/* Syslog */
	cmd->default_settings.syslog = find_config_tree_bool(cmd, log_syslog_CFG, NULL);
	if (cmd->default_settings.syslog != 1)
		fin_syslog();

	if (cmd->default_settings.syslog > 1)
		init_syslog(cmd->default_settings.syslog);

	/* Debug level for log file output */
	cmd->default_settings.debug = find_config_tree_int(cmd, log_level_CFG, NULL);
	init_debug(cmd->default_settings.debug);

	/*
	 * Suppress all non-essential stdout?
	 * -qq can override the default of 0 to 1 later.
	 * Once set to 1, there is no facility to change it back to 0.
	 */
	cmd->default_settings.silent = silent_mode() ? :
	    find_config_tree_bool(cmd, log_silent_CFG, NULL);
	init_silent(cmd->default_settings.silent);

	/* Verbose level for tty output */
	cmd->default_settings.verbose = find_config_tree_int(cmd, log_verbose_CFG, NULL);
	init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL);

	/* Log message formatting */
	init_indent(find_config_tree_bool(cmd, log_indent_CFG, NULL));
	init_abort_on_internal_errors(find_config_tree_bool(cmd, global_abort_on_internal_errors_CFG, NULL));

	cmd->default_settings.msg_prefix = find_config_tree_str_allow_empty(cmd, log_prefix_CFG, NULL);
	init_msg_prefix(cmd->default_settings.msg_prefix);

	cmd->default_settings.cmd_name = find_config_tree_bool(cmd, log_command_names_CFG, NULL);
	init_cmd_name(cmd->default_settings.cmd_name);

	/* Test mode */
	cmd->default_settings.test =
	    find_config_tree_bool(cmd, global_test_CFG, NULL);
	init_test(cmd->default_settings.test);

	/* Settings for logging to file */
	if (find_config_tree_bool(cmd, log_overwrite_CFG, NULL))
		append = 0;

	log_file = find_config_tree_str(cmd, log_file_CFG, NULL);

	if (log_file) {
		release_log_memory();
		fin_log();
		init_log_file(log_file, append);
	}

	log_file = find_config_tree_str(cmd, log_activate_file_CFG, NULL);
	if (log_file)
		init_log_direct(log_file, append);

	init_log_while_suspended(find_config_tree_bool(cmd, log_activation_CFG, NULL));

	cmd->default_settings.debug_classes = _parse_debug_classes(cmd);
	log_debug("Setting log debug classes to %d", cmd->default_settings.debug_classes);
	init_debug_classes_logged(cmd->default_settings.debug_classes);

	t = time(NULL);
	ctime_r(&t, &timebuf[0]);
	timebuf[24] = '\0';
	log_verbose("Logging initialised at %s", timebuf);

	/* Tell device-mapper about our logging */
#ifdef DEVMAPPER_SUPPORT
	if (!dm_log_is_non_default())
		dm_log_with_errno_init(print_log_libdm);
#endif
	reset_log_duplicated();
	reset_lvm_errno(1);
}

static int _check_disable_udev(const char *msg) {
	if (getenv("DM_DISABLE_UDEV")) {
		log_very_verbose("DM_DISABLE_UDEV environment variable set. "
				 "Overriding configuration to use "
				 "udev_rules=0, udev_sync=0, verify_udev_operations=1.");
		if (udev_is_running())
			log_warn("Udev is running and DM_DISABLE_UDEV environment variable is set. "
				 "Bypassing udev, LVM will %s.", msg);

		return 1;
	}

	return 0;
}

static int _check_config_by_source(struct cmd_context *cmd, config_source_t source)
{
	struct dm_config_tree *cft;
	struct cft_check_handle *handle;

	if (!(cft = get_config_tree_by_source(cmd, source)) ||
	    !(handle = get_config_tree_check_handle(cmd, cft)))
		return 1;

	return config_def_check(handle);
}

static int _check_config(struct cmd_context *cmd)
{
	int abort_on_error;

	if (!find_config_tree_bool(cmd, config_checks_CFG, NULL))
		return 1;

	abort_on_error = find_config_tree_bool(cmd, config_abort_on_errors_CFG, NULL);

	if ((!_check_config_by_source(cmd, CONFIG_STRING) ||
	    !_check_config_by_source(cmd, CONFIG_MERGED_FILES) ||
	    !_check_config_by_source(cmd, CONFIG_FILE)) &&
	    abort_on_error) {
		log_error("LVM_ configuration invalid.");
		return 0;
	}

	return 1;
}

static const char *_set_time_format(struct cmd_context *cmd)
{
	/* Compared to strftime, we do not allow "newline" character - the %n in format. */
	static const char *allowed_format_chars = "aAbBcCdDeFGghHIjklmMpPrRsStTuUVwWxXyYzZ%";
	static const char *allowed_alternative_format_chars_e = "cCxXyY";
	static const char *allowed_alternative_format_chars_o = "deHImMSuUVwWy";
	static const char *chars_to_check;
	const char *tf = find_config_tree_str(cmd, report_time_format_CFG, NULL);
	const char *p_fmt;
	size_t i;
	char c;

	if (!*tf) {
		log_error("Configured time format is empty string.");
		goto bad;
	} else {
		p_fmt = tf;
		while ((c = *p_fmt)) {
			if (c == '%') {
				c = *++p_fmt;
				if (c == 'E') {
					c = *++p_fmt;
					chars_to_check = allowed_alternative_format_chars_e;
				} else if (c == 'O') {
					c = *++p_fmt;
					chars_to_check = allowed_alternative_format_chars_o;
				} else
					chars_to_check = allowed_format_chars;

				for (i = 0; chars_to_check[i]; i++) {
					if (c == chars_to_check[i])
						break;
				}
				if (!chars_to_check[i])
					goto_bad;
			}
			else if (isprint(c))
				p_fmt++;
			else {
				log_error("Configured time format contains non-printable characters.");
				goto bad;
			}
		}
	}

	return tf;
bad:
	log_error("Invalid time format \"%s\" supplied.", tf);
	return NULL;
}

int process_profilable_config(struct cmd_context *cmd)
{
	if (!(cmd->default_settings.unit_factor =
	      dm_units_to_factor(find_config_tree_str(cmd, global_units_CFG, NULL),
				 &cmd->default_settings.unit_type, 1, NULL))) {
		log_error("Invalid units specification");
		return 0;
	}

	cmd->si_unit_consistency = find_config_tree_bool(cmd, global_si_unit_consistency_CFG, NULL);
	cmd->report_binary_values_as_numeric = find_config_tree_bool(cmd, report_binary_values_as_numeric_CFG, NULL);
	cmd->report_mark_hidden_devices = find_config_tree_bool(cmd, report_mark_hidden_devices_CFG, NULL);
	cmd->default_settings.suffix = find_config_tree_bool(cmd, global_suffix_CFG, NULL);
	cmd->report_list_item_separator = find_config_tree_str(cmd, report_list_item_separator_CFG, NULL);
	if (!(cmd->time_format = _set_time_format(cmd)))
		return 0;

	return 1;
}

static int _init_system_id(struct cmd_context *cmd)
{
	const char *source, *system_id;
	int local_set = 0;

	cmd->system_id = NULL;
	cmd->unknown_system_id = 0;

	system_id = find_config_tree_str_allow_empty(cmd, local_system_id_CFG, NULL);
	if (system_id && *system_id)
		local_set = 1;

	source = find_config_tree_str(cmd, global_system_id_source_CFG, NULL);
	if (!source)
		source = "none";

	/* Defining local system_id but not using it is probably a config mistake. */
	if (local_set && strcmp(source, "lvmlocal"))
		log_warn("WARNING: local/system_id is set, so should global/system_id_source be \"lvmlocal\" not \"%s\"?", source);

	if (!strcmp(source, "none"))
		return 1;

	if ((system_id = _system_id_from_source(cmd, source)) && *system_id) {
		cmd->system_id = system_id;
		return 1;
	}

	/*
	 * The source failed to resolve a system_id.  In this case allow
	 * VGs with no system_id to be accessed, but not VGs with a system_id.
	 */
	log_warn("WARNING: No system ID found from system_id_source %s.", source);
	cmd->unknown_system_id = 1;

	return 1;
}

static int _process_config(struct cmd_context *cmd)
{
	mode_t old_umask;
	const char *dev_ext_info_src;
	const char *read_ahead;
	struct stat st;
	const struct dm_config_node *cn;
	const struct dm_config_value *cv;
	int64_t pv_min_kb;
	int udev_disabled = 0;
	char sysfs_dir[PATH_MAX];

	if (!_check_config(cmd))
		return_0;

	/* umask */
	cmd->default_settings.umask = find_config_tree_int(cmd, global_umask_CFG, NULL);

	if ((old_umask = umask((mode_t) cmd->default_settings.umask)) !=
	    (mode_t) cmd->default_settings.umask)
		log_verbose("Set umask from %04o to %04o",
                            old_umask, cmd->default_settings.umask);

	/* dev dir */
	if (dm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
			 find_config_tree_str(cmd, devices_dir_CFG, NULL)) < 0) {
		log_error("Device directory given in config file too long");
		return 0;
	}
#ifdef DEVMAPPER_SUPPORT
	dm_set_dev_dir(cmd->dev_dir);

	if (!dm_set_uuid_prefix("LVM-"))
		return_0;
#endif

	dev_ext_info_src = find_config_tree_str(cmd, devices_external_device_info_source_CFG, NULL);
	if (dev_ext_info_src && !strcmp(dev_ext_info_src, "none"))
		init_external_device_info_source(DEV_EXT_NONE);
	else if (dev_ext_info_src && !strcmp(dev_ext_info_src, "udev"))
		init_external_device_info_source(DEV_EXT_UDEV);
	else {
		log_error("Invalid external device info source specification.");
		return 0;
	}

	/* proc dir */
	if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
			 find_config_tree_str(cmd, global_proc_CFG, NULL)) < 0) {
		log_error("Device directory given in config file too long");
		return 0;
	}

	if (*cmd->proc_dir && !dir_exists(cmd->proc_dir)) {
		log_warn("WARNING: proc dir %s not found - some checks will be bypassed",
			 cmd->proc_dir);
		cmd->proc_dir[0] = '\0';
	}

	_get_sysfs_dir(cmd, sysfs_dir, sizeof(sysfs_dir));
	dm_set_sysfs_dir(sysfs_dir);

	/* activation? */
	cmd->default_settings.activation = find_config_tree_bool(cmd, global_activation_CFG, NULL);
	set_activation(cmd->default_settings.activation, 0);

	cmd->auto_set_activation_skip = find_config_tree_bool(cmd, activation_auto_set_activation_skip_CFG, NULL);

	read_ahead = find_config_tree_str(cmd, activation_readahead_CFG, NULL);
	if (!strcasecmp(read_ahead, "auto"))
		cmd->default_settings.read_ahead = DM_READ_AHEAD_AUTO;
	else if (!strcasecmp(read_ahead, "none"))
		cmd->default_settings.read_ahead = DM_READ_AHEAD_NONE;
	else {
		log_error("Invalid readahead specification");
		return 0;
	}

	/*
	 * If udev is disabled using DM_DISABLE_UDEV environment
	 * variable, override existing config and hardcode these:
	 *   - udev_rules = 0
	 *   - udev_sync = 0
	 *   - udev_fallback = 1
	 */
	udev_disabled = _check_disable_udev("manage logical volume symlinks in device directory");

	cmd->default_settings.udev_rules = udev_disabled ? 0 :
		find_config_tree_bool(cmd, activation_udev_rules_CFG, NULL);

	cmd->default_settings.udev_sync = udev_disabled ? 0 :
		find_config_tree_bool(cmd, activation_udev_sync_CFG, NULL);

	/*
	 * Set udev_fallback lazily on first use since it requires
	 * checking DM driver version which is an extra ioctl!
	 * This also prevents unnecessary use of mapper/control.
	 * If udev is disabled globally, set fallback mode immediately.
	 */
	cmd->default_settings.udev_fallback = udev_disabled ? 1 : -1;

	init_retry_deactivation(find_config_tree_bool(cmd, activation_retry_deactivation_CFG, NULL));

	init_activation_checks(find_config_tree_bool(cmd, activation_checks_CFG, NULL));

	cmd->use_linear_target = find_config_tree_bool(cmd, activation_use_linear_target_CFG, NULL);

	cmd->stripe_filler = find_config_tree_str(cmd, activation_missing_stripe_filler_CFG, NULL);

	/* 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)? */
	if (!strcmp(cmd->stripe_filler, "/dev/ioerror") &&
	    stat(cmd->stripe_filler, &st))
		cmd->stripe_filler = "error";

	if (strcmp(cmd->stripe_filler, "error")) {
		if (stat(cmd->stripe_filler, &st)) {
			log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
				 "is invalid,", cmd->stripe_filler);
			log_warn("         stat failed: %s", strerror(errno));
			log_warn("Falling back to \"error\" missing_stripe_filler.");
			cmd->stripe_filler = "error";
		} else if (!S_ISBLK(st.st_mode)) {
			log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
				 "is not a block device.", cmd->stripe_filler);
			log_warn("Falling back to \"error\" missing_stripe_filler.");
			cmd->stripe_filler = "error";
		}
	}

	if ((cn = find_config_tree_array(cmd, activation_mlock_filter_CFG, NULL)))
		for (cv = cn->v; cv; cv = cv->next) 
			if ((cv->type != DM_CFG_STRING) || !cv->v.str[0]) 
				log_error("Ignoring invalid activation/mlock_filter entry in config file");

	cmd->metadata_read_only = find_config_tree_bool(cmd, global_metadata_read_only_CFG, NULL);

	pv_min_kb = find_config_tree_int64(cmd, devices_pv_min_size_CFG, NULL);
	if (pv_min_kb < PV_MIN_SIZE_KB) {
		log_warn("Ignoring too small pv_min_size %" PRId64 "KB, using default %dKB.",
			 pv_min_kb, PV_MIN_SIZE_KB);
		pv_min_kb = PV_MIN_SIZE_KB;
	}
	/* LVM stores sizes internally in units of 512-byte sectors. */
	init_pv_min_size((uint64_t)pv_min_kb * (1024 >> SECTOR_SHIFT));

	cmd->check_pv_dev_sizes = find_config_tree_bool(cmd, metadata_check_pv_device_sizes_CFG, NULL);

	if (!process_profilable_config(cmd))
		return_0;

	if (find_config_tree_bool(cmd, report_two_word_unknown_device_CFG, NULL))
		init_unknown_device_name("unknown device");

	init_detect_internal_vg_cache_corruption
		(find_config_tree_bool(cmd, global_detect_internal_vg_cache_corruption_CFG, NULL));

	if (!_init_system_id(cmd))
		return_0;

	return 1;
}

static int _set_tag(struct cmd_context *cmd, const char *tag)
{
	log_very_verbose("Setting host tag: %s", dm_pool_strdup(cmd->libmem, tag));

	if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
		log_error("_set_tag: str_list_add %s failed", tag);
		return 0;
	}

	return 1;
}

static int _check_host_filters(struct cmd_context *cmd, const struct dm_config_node *hn,
			       int *passes)
{
	const struct dm_config_node *cn;
	const struct dm_config_value *cv;

	*passes = 1;

	for (cn = hn; cn; cn = cn->sib) {
		if (!cn->v)
			continue;
		if (!strcmp(cn->key, "host_list")) {
			*passes = 0;
			if (cn->v->type == DM_CFG_EMPTY_ARRAY)
				continue;
			for (cv = cn->v; cv; cv = cv->next) {
				if (cv->type != DM_CFG_STRING) {
					log_error("Invalid hostname string "
						  "for tag %s", cn->key);
					return 0;
				}
				if (!strcmp(cv->v.str, cmd->hostname)) {
					*passes = 1;
					return 1;
				}
			}
		}
		if (!strcmp(cn->key, "host_filter")) {
			log_error("host_filter not supported yet");
			return 0;
		}
	}

	return 1;
}

static int _init_tags(struct cmd_context *cmd, struct dm_config_tree *cft)
{
	const struct dm_config_node *tn, *cn;
	const char *tag;
	int passes;

	/* Access tags section directly */
	if (!(tn = find_config_node(cmd, cft, tags_CFG_SECTION)) || !tn->child)
		return 1;

	/* NB hosttags 0 when already 1 intentionally does not delete the tag */
	if (!cmd->hosttags && find_config_bool(cmd, cft, tags_hosttags_CFG)) {
		/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
		if (!_set_tag(cmd, cmd->hostname))
			return_0;
		cmd->hosttags = 1;
	}

	for (cn = tn->child; cn; cn = cn->sib) {
		if (cn->v)
			continue;
		tag = cn->key;
		if (*tag == '@')
			tag++;
		if (!validate_name(tag)) {
			log_error("Invalid tag in config file: %s", cn->key);
			return 0;
		}
		if (cn->child) {
			passes = 0;
			if (!_check_host_filters(cmd, cn->child, &passes))
				return_0;
			if (!passes)
				continue;
		}
		if (!_set_tag(cmd, tag))
			return_0;
	}

	return 1;
}

static int _load_config_file(struct cmd_context *cmd, const char *tag, int local)
{
	static char config_file[PATH_MAX] = "";
	const char *filler = "";
	struct config_tree_list *cfl;

	if (*tag)
		filler = "_";
	else if (local) {
		filler = "";
		tag = "local";
	}

	if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
			 cmd->system_dir, filler, tag) < 0) {
		log_error("LVM_SYSTEM_DIR or tag was too long");
		return 0;
	}

	if (!(cfl = dm_pool_alloc(cmd->libmem, sizeof(*cfl)))) {
		log_error("config_tree_list allocation failed");
		return 0;
	}

	if (!(cfl->cft = config_file_open_and_read(config_file, CONFIG_FILE, cmd)))
		return_0;

	dm_list_add(&cmd->config_files, &cfl->list);

	if (*tag) {
		if (!_init_tags(cmd, cfl->cft))
			return_0;
	} else
		/* Use temporary copy of lvm.conf while loading other files */
		cmd->cft = cfl->cft;

	return 1;
}

/*
 * Find and read lvm.conf.
 */
static int _init_lvm_conf(struct cmd_context *cmd)
{
	/* No config file if LVM_SYSTEM_DIR is empty */
	if (!*cmd->system_dir) {
		if (!(cmd->cft = config_open(CONFIG_FILE, NULL, 0))) {
			log_error("Failed to create config tree");
			return 0;
		}
		return 1;
	}

	if (!_load_config_file(cmd, "", 0))
		return_0;

	return 1;
}

/* Read any additional config files */
static int _init_tag_configs(struct cmd_context *cmd)
{
	struct dm_str_list *sl;

	/* Tag list may grow while inside this loop */
	dm_list_iterate_items(sl, &cmd->tags) {
		if (!_load_config_file(cmd, sl->str, 0))
			return_0;
	}

	return 1;
}

static int _init_profiles(struct cmd_context *cmd)
{
	const char *dir;

	if (!(dir = find_config_tree_str(cmd, config_profile_dir_CFG, NULL)))
		return_0;

	if (!cmd->profile_params) {
		if (!(cmd->profile_params = dm_pool_zalloc(cmd->libmem, sizeof(*cmd->profile_params)))) {
			log_error("profile_params alloc failed");
			return 0;
		}
		dm_list_init(&cmd->profile_params->profiles_to_load);
		dm_list_init(&cmd->profile_params->profiles);
	}

	if (!(dm_strncpy(cmd->profile_params->dir, dir, sizeof(cmd->profile_params->dir)))) {
		log_error("_init_profiles: dm_strncpy failed");
		return 0;
	}

	return 1;
}

static struct dm_config_tree *_merge_config_files(struct cmd_context *cmd, struct dm_config_tree *cft)
{
	struct config_tree_list *cfl;

	/* Replace temporary duplicate copy of lvm.conf */
	if (cft->root) {
		if (!(cft = config_open(CONFIG_MERGED_FILES, NULL, 0))) {
			log_error("Failed to create config tree");
			return 0;
		}
	}

	dm_list_iterate_items(cfl, &cmd->config_files) {
		/* Merge all config trees into cmd->cft using merge/tag rules */
		if (!merge_config_tree(cmd, cft, cfl->cft, CONFIG_MERGE_TYPE_TAGS))
			return_0;
	}

	return cft;
}

static void _destroy_tags(struct cmd_context *cmd)
{
	struct dm_list *slh, *slht;

	dm_list_iterate_safe(slh, slht, &cmd->tags) {
		dm_list_del(slh);
	}
}

int config_files_changed(struct cmd_context *cmd)
{
	struct config_tree_list *cfl;

	dm_list_iterate_items(cfl, &cmd->config_files) {
		if (config_file_changed(cfl->cft))
			return 1;
	}

	return 0;
}

static void _destroy_config(struct cmd_context *cmd)
{
	struct config_tree_list *cfl;
	struct dm_config_tree *cft;
	struct profile *profile, *tmp_profile;

	/*
	 * Configuration cascade:
	 * CONFIG_STRING -> CONFIG_PROFILE -> CONFIG_FILE/CONFIG_MERGED_FILES
	 */

	/* CONFIG_FILE/CONFIG_MERGED_FILES */
	if ((cft = remove_config_tree_by_source(cmd, CONFIG_MERGED_FILES)))
		config_destroy(cft);
	else
		remove_config_tree_by_source(cmd, CONFIG_FILE);

	dm_list_iterate_items(cfl, &cmd->config_files)
		config_destroy(cfl->cft);
	dm_list_init(&cmd->config_files);

	/* CONFIG_PROFILE */
	if (cmd->profile_params) {
		remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND);
		remove_config_tree_by_source(cmd, CONFIG_PROFILE_METADATA);
		/*
		 * Destroy config trees for any loaded profiles and
		 * move these profiles to profile_to_load list.
		 * Whenever these profiles are referenced later,
		 * they will get loaded again automatically.
		 */
		dm_list_iterate_items_safe(profile, tmp_profile, &cmd->profile_params->profiles) {
			config_destroy(profile->cft);
			profile->cft = NULL;
			dm_list_move(&cmd->profile_params->profiles_to_load, &profile->list);
		}
	}

	/* CONFIG_STRING */
	if ((cft = remove_config_tree_by_source(cmd, CONFIG_STRING)))
		config_destroy(cft);

	if (cmd->cft)
		log_error(INTERNAL_ERROR "_destroy_config: "
			  "cmd config tree not destroyed fully");
}

static int _init_dev_cache(struct cmd_context *cmd)
{
	const struct dm_config_node *cn;
	const struct dm_config_value *cv;
	size_t len, udev_dir_len = strlen(DM_UDEV_DEV_DIR);
	int len_diff;
	int device_list_from_udev;

	init_dev_disable_after_error_count(
		find_config_tree_int(cmd, devices_disable_after_error_count_CFG, NULL));

	if (!dev_cache_init(cmd))
		return_0;

	/*
	 * Override existing config and hardcode device_list_from_udev = 0 if:
	 *   - udev is not running
	 *   - udev is disabled using DM_DISABLE_UDEV environment variable
	 */
	if (_check_disable_udev("obtain device list by scanning device directory"))
		device_list_from_udev = 0;
	else
		device_list_from_udev = udev_is_running() ?
			find_config_tree_bool(cmd, devices_obtain_device_list_from_udev_CFG, NULL) : 0;

	init_obtain_device_list_from_udev(device_list_from_udev);

	if (!(cn = find_config_tree_array(cmd, devices_scan_CFG, NULL))) {
		log_error(INTERNAL_ERROR "Unable to find configuration for devices/scan.");
		return_0;
	}

	for (cv = cn->v; cv; cv = cv->next) {
		if (cv->type != DM_CFG_STRING) {
			log_error("Invalid string in config file: "
				  "devices/scan");
			return 0;
		}

		if (device_list_from_udev) {
			len = strlen(cv->v.str);

			/*
			 * DM_UDEV_DEV_DIR always has '/' at its end.
			 * If the item in the conf does not have it, be sure
			 * to make the right comparison without the '/' char!
			 */
			len_diff = len && cv->v.str[len - 1] != '/' ?
					udev_dir_len - 1 != len :
					udev_dir_len != len;

			if (len_diff || strncmp(DM_UDEV_DEV_DIR, cv->v.str, len)) {
				log_very_verbose("Non standard udev dir %s, resetting "
						 "devices/obtain_device_list_from_udev.",
						 cv->v.str);
				device_list_from_udev = 0;
				init_obtain_device_list_from_udev(0);
			}
		}

		if (!dev_cache_add_dir(cv->v.str)) {
			log_error("Failed to add %s to internal device cache",
				  cv->v.str);
			return 0;
		}
	}

	if (!(cn = find_config_tree_array(cmd, devices_loopfiles_CFG, NULL)))
		return 1;

	for (cv = cn->v; cv; cv = cv->next) {
		if (cv->type != DM_CFG_STRING) {
			log_error("Invalid string in config file: "
				  "devices/loopfiles");
			return 0;
		}

		if (!dev_cache_add_loopfile(cv->v.str)) {
			log_error("Failed to add loopfile %s to internal "
				  "device cache", cv->v.str);
			return 0;
		}
	}


	return 1;
}

#define MAX_FILTERS 9

static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
{
	int nr_filt = 0;
	const struct dm_config_node *cn;
	struct dev_filter *filters[MAX_FILTERS] = { 0 };
	struct dev_filter *composite;

	/*
	 * Filters listed in order: top one gets applied first.
	 * Failure to initialise some filters is not fatal.
	 * Update MAX_FILTERS definition above when adding new filters.
	 */

	/*
	 * sysfs filter. Only available on 2.6 kernels.  Non-critical.
	 * Listed first because it's very efficient at eliminating
	 * unavailable devices.
	 */
	if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) {
		if ((filters[nr_filt] = sysfs_filter_create()))
			nr_filt++;
	}

	/* internal filter used by command processing. */
	if (!(filters[nr_filt] = internal_filter_create())) {
		log_error("Failed to create internal device filter");
		goto bad;
	}
	nr_filt++;

	/* global regex filter. Optional. */
	if ((cn = find_config_tree_node(cmd, devices_global_filter_CFG, NULL))) {
		if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
			log_error("Failed to create global regex device filter");
			goto bad;
		}
		nr_filt++;
	}

	/* regex filter. Optional. */
	if (!lvmetad_used()) {
		if ((cn = find_config_tree_node(cmd, devices_filter_CFG, NULL))) {
			if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
				log_error("Failed to create regex device filter");
				goto bad;
			}
			nr_filt++;
		}
	}

	/* device type filter. Required. */
	if (!(filters[nr_filt] = lvm_type_filter_create(cmd->dev_types))) {
		log_error("Failed to create lvm type filter");
		goto bad;
	}
	nr_filt++;

	/* usable device filter. Required. */
	if (!(filters[nr_filt] = usable_filter_create(cmd->dev_types,
						      lvmetad_used() ? FILTER_MODE_PRE_LVMETAD
								     : FILTER_MODE_NO_LVMETAD))) {
		log_error("Failed to create usabled device filter");
		goto bad;
	}
	nr_filt++;

	/* mpath component filter. Optional, non-critical. */
	if (find_config_tree_bool(cmd, devices_multipath_component_detection_CFG, NULL)) {
		if ((filters[nr_filt] = mpath_filter_create(cmd->dev_types)))
			nr_filt++;
	}

	/* partitioned device filter. Required. */
	if (!(filters[nr_filt] = partitioned_filter_create(cmd->dev_types))) {
		log_error("Failed to create partitioned device filter");
		goto bad;
	}
	nr_filt++;

	/* md component filter. Optional, non-critical. */
	if (find_config_tree_bool(cmd, devices_md_component_detection_CFG, NULL)) {
		init_md_filtering(1);
		if ((filters[nr_filt] = md_filter_create(cmd->dev_types)))
			nr_filt++;
	}

	/* firmware raid filter. Optional, non-critical. */
	if (find_config_tree_bool(cmd, devices_fw_raid_component_detection_CFG, NULL)) {
		init_fwraid_filtering(1);
		if ((filters[nr_filt] = fwraid_filter_create(cmd->dev_types)))
			nr_filt++;
	}

	if (!(composite = composite_filter_create(nr_filt, 1, filters)))
		goto_bad;

	return composite;

bad:
	while (--nr_filt >= 0)
		 filters[nr_filt]->destroy(filters[nr_filt]);

	return NULL;
}

/*
 * The way the filtering is initialized depends on whether lvmetad is uesd or not.
 *
 * If lvmetad is used, there are three filter chains:
 *
 *   - cmd->lvmetad_filter - the lvmetad filter chain used when scanning devs for lvmetad update:
 *     sysfs filter -> internal filter -> global regex filter -> type filter ->
 *     usable device filter(FILTER_MODE_PRE_LVMETAD) ->
 *     mpath component filter -> partitioned filter ->
 *     md component filter -> fw raid filter
 *
 *   - cmd->filter - the filter chain used for lvmetad responses:
 *     persistent filter -> regex_filter -> usable device filter(FILTER_MODE_POST_LVMETAD)
 *
 *   - cmd->full_filter - the filter chain used for all the remaining situations:
 *     cmd->lvmetad_filter -> cmd->filter
 *
 * If lvmetad is not used, there's just one filter chain:
 *
 *   - cmd->filter == cmd->full_filter:
 *     persistent filter -> sysfs filter -> internal filter -> global regex filter ->
 *     regex_filter -> type filter -> usable device filter(FILTER_MODE_NO_LVMETAD) ->
 *     mpath component filter -> partitioned filter -> md component filter -> fw raid filter
 *
 */
int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
{
	const char *dev_cache;
	struct dev_filter *filter = NULL, *filter_components[2] = {0};
	int nr_filt;
	struct stat st;
	const struct dm_config_node *cn;
	struct timespec ts, cts;

	if (!cmd->initialized.connections) {
		log_error(INTERNAL_ERROR "connections must be initialized before filters");
		return 0;
	}

	cmd->dump_filter = 0;

	cmd->lvmetad_filter = _init_lvmetad_filter_chain(cmd);
	if (!cmd->lvmetad_filter)
		goto_bad;

	init_ignore_suspended_devices(find_config_tree_bool(cmd, devices_ignore_suspended_devices_CFG, NULL));
	init_ignore_lvm_mirrors(find_config_tree_bool(cmd, devices_ignore_lvm_mirrors_CFG, NULL));

	/*
	 * If lvmetad is used, there's a separation between pre-lvmetad filter chain
	 * ("cmd->lvmetad_filter") applied only if scanning for lvmetad update and
	 * post-lvmetad filter chain ("filter") applied on each lvmetad response.
	 * However, if lvmetad is not used, these two chains are not separated
	 * and we use exactly one filter chain during device scanning ("filter"
	 * that includes also "cmd->lvmetad_filter" chain).
	 */
	/* filter component 0 */
	if (lvmetad_used()) {
		nr_filt = 0;
		if ((cn = find_config_tree_array(cmd, devices_filter_CFG, NULL))) {
			if (!(filter_components[nr_filt] = regex_filter_create(cn->v))) {
				log_verbose("Failed to create regex device filter.");
				goto bad;
			}
			nr_filt++;
		}
		if (!(filter_components[nr_filt] = usable_filter_create(cmd->dev_types, FILTER_MODE_POST_LVMETAD))) {
			log_verbose("Failed to create usable device filter.");
			goto bad;
		}
		nr_filt++;
		if (!(filter = composite_filter_create(nr_filt, 0, filter_components)))
			goto_bad;
	} else {
		filter = cmd->lvmetad_filter;
		cmd->lvmetad_filter = NULL;
	}

	if (!(dev_cache = find_config_tree_str(cmd, devices_cache_CFG, NULL)))
		goto_bad;

	if (!(filter = persistent_filter_create(cmd->dev_types, filter, dev_cache))) {
		log_verbose("Failed to create persistent device filter.");
		goto bad;
	}

	cmd->filter = filter;

	if (lvmetad_used()) {
		nr_filt = 0;
		filter_components[nr_filt] = cmd->lvmetad_filter;
		nr_filt++;
		filter_components[nr_filt] = cmd->filter;
		nr_filt++;
		if (!(cmd->full_filter = composite_filter_create(nr_filt, 0, filter_components)))
			goto_bad;
	} else
		cmd->full_filter = filter;

	/* Should we ever dump persistent filter state? */
	if (find_config_tree_bool(cmd, devices_write_cache_state_CFG, NULL))
		cmd->dump_filter = 1;

	if (!*cmd->system_dir)
		cmd->dump_filter = 0;

	/*
	 * Only load persistent filter device cache on startup if it is newer
	 * than the config file and this is not a long-lived process. Also avoid
	 * it when lvmetad is enabled.
	 */
	if (!find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL) &&
	    load_persistent_cache && !cmd->is_long_lived &&
	    !stat(dev_cache, &st)) {
		lvm_stat_ctim(&ts, &st);
		cts = config_file_timestamp(cmd->cft);
		if (timespeccmp(&ts, &cts, >) &&
		    !persistent_filter_load(cmd->filter, NULL))
			log_verbose("Failed to load existing device cache from %s",
				    dev_cache);
	}

	cmd->initialized.filters = 1;
	return 1;
bad:
	if (!filter) {
		/*
		 * composite filter not created - destroy
		 * each component directly
		 */
		if (filter_components[0])
			filter_components[0]->destroy(filter_components[0]);
		if (filter_components[1])
			filter_components[1]->destroy(filter_components[1]);
	} else {
		/*
		 * composite filter created - destroy it - this
		 * will also destroy any of its components
		 */
		filter->destroy(filter);
	}

	/* if lvmetad is used, the cmd->lvmetad_filter is separate */
	if (cmd->lvmetad_filter)
		cmd->lvmetad_filter->destroy(cmd->lvmetad_filter);

	cmd->initialized.filters = 0;
	return 0;
}

struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format)
{
        struct format_type *fmt;

        dm_list_iterate_items(fmt, &cmd->formats)
                if (!strcasecmp(fmt->name, format) ||
                    !strcasecmp(fmt->name + 3, format) ||
                    (fmt->alias && !strcasecmp(fmt->alias, format)))
                        return fmt;

        return NULL;
}

static int _init_formats(struct cmd_context *cmd)
{
	const char *format;

	struct format_type *fmt;

#ifdef HAVE_LIBDL
	const struct dm_config_node *cn;
#endif

#ifdef LVM1_INTERNAL
	if (!(fmt = init_lvm1_format(cmd)))
		return 0;
	fmt->library = NULL;
	dm_list_add(&cmd->formats, &fmt->list);
#endif

#ifdef POOL_INTERNAL
	if (!(fmt = init_pool_format(cmd)))
		return 0;
	fmt->library = NULL;
	dm_list_add(&cmd->formats, &fmt->list);
#endif

#ifdef HAVE_LIBDL
	/* Load any formats in shared libs if not static */
	if (!is_static() &&
	    (cn = find_config_tree_array(cmd, global_format_libraries_CFG, NULL))) {

		const struct dm_config_value *cv;
		struct format_type *(*init_format_fn) (struct cmd_context *);
		void *lib;

		for (cv = cn->v; cv; cv = cv->next) {
			if (cv->type != DM_CFG_STRING) {
				log_error("Invalid string in config file: "
					  "global/format_libraries");
				return 0;
			}
			if (!(lib = load_shared_library(cmd, cv->v.str,
							"format", 0)))
				return_0;

			if (!(init_format_fn = dlsym(lib, "init_format"))) {
				log_error("Shared library %s does not contain "
					  "format functions", cv->v.str);
				dlclose(lib);
				return 0;
			}

			if (!(fmt = init_format_fn(cmd))) {
				dlclose(lib);
				return_0;
			}

			fmt->library = lib;
			dm_list_add(&cmd->formats, &fmt->list);
		}
	}
#endif

	if (!(fmt = create_text_format(cmd)))
		return 0;
	fmt->library = NULL;
	dm_list_add(&cmd->formats, &fmt->list);

	cmd->fmt_backup = fmt;

	format = find_config_tree_str(cmd, global_format_CFG, NULL);

	dm_list_iterate_items(fmt, &cmd->formats) {
		if (!strcasecmp(fmt->name, format) ||
		    (fmt->alias && !strcasecmp(fmt->alias, format))) {
			cmd->default_settings.fmt_name = fmt->name;
			cmd->fmt = fmt;
			return 1;
		}
	}

	log_error("_init_formats: Default format (%s) not found", format);
	return 0;
}

int init_lvmcache_orphans(struct cmd_context *cmd)
{
	struct format_type *fmt;

	dm_list_iterate_items(fmt, &cmd->formats)
		if (!lvmcache_add_orphan_vginfo(fmt->orphan_vg_name, fmt))
			return_0;

	return 1;
}

struct segtype_library {
	struct cmd_context *cmd;
	void *lib;
	const char *libname;
};

int lvm_register_segtype(struct segtype_library *seglib,
			 struct segment_type *segtype)
{
	struct segment_type *segtype2;

	segtype->library = seglib->lib;

	dm_list_iterate_items(segtype2, &seglib->cmd->segtypes) {
		if (strcmp(segtype2->name, segtype->name))
			continue;
		log_error("Duplicate segment type %s: "
			  "unloading shared library %s",
			  segtype->name, seglib->libname);
		segtype->ops->destroy(segtype);
		return 0;
	}

	dm_list_add(&seglib->cmd->segtypes, &segtype->list);

	return 1;
}

static int _init_single_segtype(struct cmd_context *cmd,
				struct segtype_library *seglib)
{
	struct segment_type *(*init_segtype_fn) (struct cmd_context *);
	struct segment_type *segtype;

	if (!(init_segtype_fn = dlsym(seglib->lib, "init_segtype"))) {
		log_error("Shared library %s does not contain segment type "
			  "functions", seglib->libname);
		return 0;
	}

	if (!(segtype = init_segtype_fn(seglib->cmd)))
		return_0;

	return lvm_register_segtype(seglib, segtype);
}

static int _init_segtypes(struct cmd_context *cmd)
{
	int i;
	struct segment_type *segtype;
	struct segtype_library seglib = { .cmd = cmd, .lib = NULL };
	struct segment_type *(*init_segtype_array[])(struct cmd_context *cmd) = {
		init_striped_segtype,
		init_zero_segtype,
		init_error_segtype,
		/* disabled until needed init_free_segtype, */
#ifdef SNAPSHOT_INTERNAL
		init_snapshot_segtype,
#endif
#ifdef MIRRORED_INTERNAL
		init_mirrored_segtype,
#endif
		NULL
	};

#ifdef HAVE_LIBDL
	const struct dm_config_node *cn;
#endif

	for (i = 0; init_segtype_array[i]; i++) {
		if (!(segtype = init_segtype_array[i](cmd)))
			return 0;
		segtype->library = NULL;
		dm_list_add(&cmd->segtypes, &segtype->list);
	}

#ifdef REPLICATOR_INTERNAL
	if (!init_replicator_segtype(cmd, &seglib))
		return 0;
#endif

#ifdef RAID_INTERNAL
	if (!init_raid_segtypes(cmd, &seglib))
		return 0;
#endif

#ifdef THIN_INTERNAL
	if (!init_thin_segtypes(cmd, &seglib))
		return 0;
#endif

#ifdef CACHE_INTERNAL
	if (!init_cache_segtypes(cmd, &seglib))
		return 0;
#endif

#ifdef HAVE_LIBDL
	/* Load any formats in shared libs unless static */
	if (!is_static() &&
	    (cn = find_config_tree_array(cmd, global_segment_libraries_CFG, NULL))) {

		const struct dm_config_value *cv;
		int (*init_multiple_segtypes_fn) (struct cmd_context *,
						  struct segtype_library *);

		for (cv = cn->v; cv; cv = cv->next) {
			if (cv->type != DM_CFG_STRING) {
				log_error("Invalid string in config file: "
					  "global/segment_libraries");
				return 0;
			}
			seglib.libname = cv->v.str;
			if (!(seglib.lib = load_shared_library(cmd,
							seglib.libname,
							"segment type", 0)))
				return_0;

			if ((init_multiple_segtypes_fn =
			    dlsym(seglib.lib, "init_multiple_segtypes"))) {
				if (dlsym(seglib.lib, "init_segtype"))
					log_warn("WARNING: Shared lib %s has "
						 "conflicting init fns.  Using"
						 " init_multiple_segtypes().",
						 seglib.libname);
			} else
				init_multiple_segtypes_fn =
				    _init_single_segtype;
 
			if (!init_multiple_segtypes_fn(cmd, &seglib)) {
				struct dm_list *sgtl, *tmp;
				log_error("init_multiple_segtypes() failed: "
					  "Unloading shared library %s",
					  seglib.libname);
				dm_list_iterate_safe(sgtl, tmp, &cmd->segtypes) {
					segtype = dm_list_item(sgtl, struct segment_type);
					if (segtype->library == seglib.lib) {
						dm_list_del(&segtype->list);
						segtype->ops->destroy(segtype);
					}
				}
				dlclose(seglib.lib);
				return_0;
			}
		}
	}
#endif

	return 1;
}

static int _init_hostname(struct cmd_context *cmd)
{
	struct utsname uts;

	if (uname(&uts)) {
		log_sys_error("uname", "_init_hostname");
		return 0;
	}

	if (!(cmd->hostname = dm_pool_strdup(cmd->libmem, uts.nodename))) {
		log_error("_init_hostname: dm_pool_strdup failed");
		return 0;
	}

	if (!(cmd->kernel_vsn = dm_pool_strdup(cmd->libmem, uts.release))) {
		log_error("_init_hostname: dm_pool_strdup kernel_vsn failed");
		return 0;
	}

	return 1;
}

static int _init_backup(struct cmd_context *cmd)
{
	uint32_t days, min;
	const char *dir;

	if (!cmd->system_dir[0]) {
		log_warn("WARNING: Metadata changes will NOT be backed up");
		backup_init(cmd, "", 0);
		archive_init(cmd, "", 0, 0, 0);
		return 1;
	}

	/* set up archiving */
	cmd->default_settings.archive =
	    find_config_tree_bool(cmd, backup_archive_CFG, NULL);

	days = (uint32_t) find_config_tree_int(cmd, backup_retain_days_CFG, NULL);

	min = (uint32_t) find_config_tree_int(cmd, backup_retain_min_CFG, NULL);

	if (!(dir = find_config_tree_str(cmd, backup_archive_dir_CFG, NULL)))
		return_0;

	if (!archive_init(cmd, dir, days, min,
			  cmd->default_settings.archive)) {
		log_debug("archive_init failed.");
		return 0;
	}

	/* set up the backup */
	cmd->default_settings.backup = find_config_tree_bool(cmd, backup_backup_CFG, NULL);

	if (!(dir = find_config_tree_str(cmd, backup_backup_dir_CFG, NULL)))
		return_0;

	if (!backup_init(cmd, dir, cmd->default_settings.backup)) {
		log_debug("backup_init failed.");
		return 0;
	}

	return 1;
}

static void _init_rand(struct cmd_context *cmd)
{
	if (read_urandom(&cmd->rand_seed, sizeof(cmd->rand_seed))) {
		reset_lvm_errno(1);
		return;
	}

	cmd->rand_seed = (unsigned) time(NULL) + (unsigned) getpid();
	reset_lvm_errno(1);
}

static void _init_globals(struct cmd_context *cmd)
{
	init_full_scan_done(0);
	init_mirror_in_sync(0);
}

/*
 * Close and reopen stream on file descriptor fd.
 */
static int _reopen_stream(FILE *stream, int fd, const char *mode, const char *name, FILE **new_stream)
{
	int fd_copy, new_fd;

	if ((fd_copy = dup(fd)) < 0) {
		log_sys_error("dup", name);
		return 0;
	}

	if (fclose(stream))
		log_sys_error("fclose", name);

	if ((new_fd = dup2(fd_copy, fd)) < 0)
		log_sys_error("dup2", name);
	else if (new_fd != fd)
		log_error("dup2(%d, %d) returned %d", fd_copy, fd, new_fd);

	if (close(fd_copy) < 0)
		log_sys_error("close", name);

	if (!(*new_stream = fdopen(fd, mode))) {
		log_sys_error("fdopen", name);
		return 0;
	}

	return 1;
}

/*
 * init_connections();
 *   _init_lvmetad();
 *     lvmetad_disconnect();  (close previous connection)
 *     lvmetad_set_socket();  (set path from config)
 *     lvmetad_set_token();   (set token from filter config)
 *     if (find_config(use_lvmetad))
 *       lvmetad_connect();
 *
 * If lvmetad_connect() is successful, lvmetad_used() will
 * return 1.
 *
 * If the config has use_lvmetad=0, then lvmetad_connect()
 * will not be called, and lvmetad_used() will return 0.
 *
 * Other code should use lvmetad_used() to check if the
 * command is using lvmetad.
 *
 */

static int _init_lvmetad(struct cmd_context *cmd)
{
	const struct dm_config_node *cn;
	const char *lvmetad_socket;

	lvmetad_disconnect();

	lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
	if (!lvmetad_socket)
		lvmetad_socket = DEFAULT_RUN_DIR "/lvmetad.socket";

	/* TODO?
		lvmetad_socket = find_config_tree_str(cmd, "lvmetad/socket_path",
						      DEFAULT_RUN_DIR "/lvmetad.socket");
	*/

	lvmetad_set_socket(lvmetad_socket);
	cn = find_config_tree_array(cmd, devices_global_filter_CFG, NULL);
	lvmetad_set_token(cn ? cn->v : NULL);

	if (find_config_tree_int(cmd, global_locking_type_CFG, NULL) == 3 &&
	    find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL)) {
		log_warn("WARNING: Not using lvmetad because locking_type is 3 (clustered).");
		return 1;
	}

	if (!find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL)) {
		if (lvmetad_pidfile_present()) {
			log_warn("WARNING: Not using lvmetad because config setting use_lvmetad=0.");
			log_warn("WARNING: To avoid corruption, rescan devices to make changes visible (pvscan --cache).");
		}
		return 1;
	}

	if (!lvmetad_connect(cmd)) {
		log_warn("WARNING: Failed to connect to lvmetad. Falling back to device scanning.");
		return 1;
	}

	if (!lvmetad_used()) {
		/* This should never happen. */
		log_error(INTERNAL_ERROR "lvmetad setup incorrect");
		return 0;
	}

	return 1;
}

static int _init_lvmpolld(struct cmd_context *cmd)
{
	const char *lvmpolld_socket;

	lvmpolld_disconnect();

	lvmpolld_socket = getenv("LVM_LVMPOLLD_SOCKET");
	if (!lvmpolld_socket)
		lvmpolld_socket = DEFAULT_RUN_DIR "/lvmpolld.socket";
	lvmpolld_set_socket(lvmpolld_socket);

	lvmpolld_set_active(find_config_tree_bool(cmd, global_use_lvmpolld_CFG, NULL));
	return 1;
}

int init_connections(struct cmd_context *cmd)
{

	if (!_init_lvmetad(cmd)) {
		log_error("Failed to initialize lvmetad connection.");
		goto bad;
	}

	if (!_init_lvmpolld(cmd)) {
		log_error("Failed to initialize lvmpolld connection.");
		goto bad;
	}

	cmd->initialized.connections = 1;
	return 1;
bad:
	cmd->initialized.connections = 0;
	return 0;
}

void destroy_config_context(struct cmd_context *cmd)
{
	_destroy_config(cmd);

	if (cmd->mem)
		dm_pool_destroy(cmd->mem);
	if (cmd->libmem)
		dm_pool_destroy(cmd->libmem);

	dm_free(cmd);
}

/*
 * A "config context" is a very light weight toolcontext that
 * is only used for reading config settings from lvm.conf.
 */
struct cmd_context *create_config_context(void)
{
	struct cmd_context *cmd;

	if (!(cmd = dm_zalloc(sizeof(*cmd))))
		goto_out;

	strcpy(cmd->system_dir, DEFAULT_SYS_DIR);

	if (!_get_env_vars(cmd))
		goto_out;

	if (!(cmd->libmem = dm_pool_create("library", 4 * 1024)))
		goto_out;

	dm_list_init(&cmd->config_files);

	if (!_init_lvm_conf(cmd))
		goto_out;

	return cmd;
out:
	if (cmd)
		destroy_config_context(cmd);
	return NULL;
}

/* Entry point */
struct cmd_context *create_toolcontext(unsigned is_long_lived,
				       const char *system_dir,
				       unsigned set_buffering,
				       unsigned threaded,
				       unsigned set_connections,
				       unsigned set_filters)
{
	struct cmd_context *cmd;
	FILE *new_stream;
	int flags;

#ifdef M_MMAP_MAX
	mallopt(M_MMAP_MAX, 0);
#endif

	if (!setlocale(LC_ALL, ""))
		log_very_verbose("setlocale failed");

#ifdef INTL_PACKAGE
	bindtextdomain(INTL_PACKAGE, LOCALEDIR);
#endif

	init_syslog(DEFAULT_LOG_FACILITY);

	if (!(cmd = dm_zalloc(sizeof(*cmd)))) {
		log_error("Failed to allocate command context");
		return NULL;
	}
	cmd->is_long_lived = is_long_lived;
	cmd->threaded = threaded ? 1 : 0;
	cmd->handles_missing_pvs = 0;
	cmd->handles_unknown_segments = 0;
	cmd->independent_metadata_areas = 0;
	cmd->ignore_clustered_vgs = 0;
	cmd->hosttags = 0;
	dm_list_init(&cmd->arg_value_groups);
	dm_list_init(&cmd->formats);
	dm_list_init(&cmd->segtypes);
	dm_list_init(&cmd->tags);
	dm_list_init(&cmd->config_files);
	label_init();

	/* FIXME Make this configurable? */
	reset_lvm_errno(1);

#ifndef VALGRIND_POOL
	/* Set in/out stream buffering before glibc */
	if (set_buffering) {
		/* Allocate 2 buffers */
		if (!(cmd->linebuffer = dm_malloc(2 * linebuffer_size))) {
			log_error("Failed to allocate line buffer.");
			goto out;
		}

		/* nohup might set stdin O_WRONLY ! */
		if (is_valid_fd(STDIN_FILENO) &&
		    ((flags = fcntl(STDIN_FILENO, F_GETFL)) > 0) &&
		    (flags & O_ACCMODE) != O_WRONLY) {
			if (!_reopen_stream(stdin, STDIN_FILENO, "r", "stdin", &new_stream))
				goto_out;
			stdin = new_stream;
			if (setvbuf(stdin, cmd->linebuffer, _IOLBF, linebuffer_size)) {
				log_sys_error("setvbuf", "");
				goto out;
			}
		}

		if (is_valid_fd(STDOUT_FILENO) &&
		    ((flags = fcntl(STDOUT_FILENO, F_GETFL)) > 0) &&
		    (flags & O_ACCMODE) != O_RDONLY) {
			if (!_reopen_stream(stdout, STDOUT_FILENO, "w", "stdout", &new_stream))
				goto_out;
			stdout = new_stream;
			if (setvbuf(stdout, cmd->linebuffer + linebuffer_size,
				     _IOLBF, linebuffer_size)) {
				log_sys_error("setvbuf", "");
				goto out;
			}
		}
		/* Buffers are used for lines without '\n' */
	} else
		/* Without buffering, must not use stdin/stdout */
		init_silent(1);
#endif

	/*
	 * Environment variable LVM_SYSTEM_DIR overrides this below.
	 */
        if (system_dir)
		strncpy(cmd->system_dir, system_dir, sizeof(cmd->system_dir) - 1);
	else
		strcpy(cmd->system_dir, DEFAULT_SYS_DIR);

	if (!_get_env_vars(cmd))
		goto_out;

	/* Create system directory if it doesn't already exist */
	if (*cmd->system_dir && !dm_create_dir(cmd->system_dir)) {
		log_error("Failed to create LVM2 system dir for metadata backups, config "
			  "files and internal cache.");
		log_error("Set environment variable LVM_SYSTEM_DIR to alternative location "
			  "or empty string.");
		goto out;
	}

	if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) {
		log_error("Library memory pool creation failed");
		goto out;
	}

	if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
		log_error("Command memory pool creation failed");
		goto out;
	}

	if (!_init_lvm_conf(cmd))
		goto_out;

	_init_logging(cmd);

	if (!_init_hostname(cmd))
		goto_out;

	if (!_init_tags(cmd, cmd->cft))
		goto_out;

	/* Load lvmlocal.conf */
	if (*cmd->system_dir && !_load_config_file(cmd, "", 1))
		goto_out;

	if (!_init_tag_configs(cmd))
		goto_out;

	if (!(cmd->cft = _merge_config_files(cmd, cmd->cft)))
		goto_out;

	if (!_process_config(cmd))
		goto_out;

	if (!_init_profiles(cmd))
		goto_out;

	if (!(cmd->dev_types = create_dev_types(cmd->proc_dir,
						find_config_tree_array(cmd, devices_types_CFG, NULL))))
		goto_out;

	if (!_init_dev_cache(cmd))
		goto_out;

	memlock_init(cmd);

	if (!_init_formats(cmd))
		goto_out;

	if (!init_lvmcache_orphans(cmd))
		goto_out;

	dm_list_init(&cmd->unused_duplicate_devs);

	if (!_init_segtypes(cmd))
		goto_out;

	if (!_init_backup(cmd))
		goto_out;

	_init_rand(cmd);

	_init_globals(cmd);

	if (set_connections && !init_connections(cmd))
		goto_out;

	if (set_filters && !init_filters(cmd, 1))
		goto_out;

	cmd->default_settings.cache_vgmetadata = 1;
	cmd->current_settings = cmd->default_settings;

	cmd->initialized.config = 1;
out:
	if (!cmd->initialized.config) {
		destroy_toolcontext(cmd);
		cmd = NULL;
	}


	return cmd;
}

static void _destroy_formats(struct cmd_context *cmd, struct dm_list *formats)
{
	struct dm_list *fmtl, *tmp;
	struct format_type *fmt;
	void *lib;

	dm_list_iterate_safe(fmtl, tmp, formats) {
		fmt = dm_list_item(fmtl, struct format_type);
		dm_list_del(&fmt->list);
		lib = fmt->library;
		fmt->ops->destroy(fmt);
#ifdef HAVE_LIBDL
		if (lib)
			dlclose(lib);
#endif
	}

	cmd->independent_metadata_areas = 0;
}

static void _destroy_segtypes(struct dm_list *segtypes)
{
	struct dm_list *sgtl, *tmp;
	struct segment_type *segtype;
	void *lib;

	dm_list_iterate_safe(sgtl, tmp, segtypes) {
		segtype = dm_list_item(sgtl, struct segment_type);
		dm_list_del(&segtype->list);
		lib = segtype->library;
		segtype->ops->destroy(segtype);
#ifdef HAVE_LIBDL
		/*
		 * If no segtypes remain from this library, close it.
		 */
		if (lib) {
			struct segment_type *segtype2;
			dm_list_iterate_items(segtype2, segtypes)
				if (segtype2->library == lib)
					goto skip_dlclose;
			dlclose(lib);
skip_dlclose:
			;
		}
#endif
	}
}

static void _destroy_dev_types(struct cmd_context *cmd)
{
	if (!cmd->dev_types)
		return;

	dm_free(cmd->dev_types);
	cmd->dev_types = NULL;
}

static void _destroy_filters(struct cmd_context *cmd)
{
	if (cmd->full_filter) {
		cmd->full_filter->destroy(cmd->full_filter);
		cmd->lvmetad_filter = cmd->filter = cmd->full_filter = NULL;
	}
	cmd->initialized.filters = 0;
}

int refresh_filters(struct cmd_context *cmd)
{
	int r, saved_ignore_suspended_devices = ignore_suspended_devices();

	if (!cmd->initialized.filters)
		/* if filters not initialized, there's nothing to refresh */
		return 1;

	_destroy_filters(cmd);
	if (!(r = init_filters(cmd, 0)))
                stack;

	/*
	 * During repair code must not reset suspended flag.
	 */
	init_ignore_suspended_devices(saved_ignore_suspended_devices);

	return r;
}

int refresh_toolcontext(struct cmd_context *cmd)
{
	struct dm_config_tree *cft_cmdline, *cft_tmp;
	const char *profile_command_name, *profile_metadata_name;
	struct profile *profile;

	log_verbose("Reloading config files");

	/*
	 * Don't update the persistent filter cache as we will
	 * perform a full rescan.
	 */

	activation_release();
	lvmcache_destroy(cmd, 0, 0);
	label_exit();
	_destroy_segtypes(&cmd->segtypes);
	_destroy_formats(cmd, &cmd->formats);

	if (!dev_cache_exit())
		stack;
	_destroy_dev_types(cmd);
	_destroy_tags(cmd);

	/* save config string passed on the command line */
	cft_cmdline = remove_config_tree_by_source(cmd, CONFIG_STRING);

	/* save the global profile name used */
	profile_command_name = cmd->profile_params->global_command_profile ?
				cmd->profile_params->global_command_profile->name : NULL;
	profile_metadata_name = cmd->profile_params->global_metadata_profile ?
				cmd->profile_params->global_metadata_profile->name : NULL;

	_destroy_config(cmd);

	cmd->initialized.config = 0;

	cmd->hosttags = 0;

	cmd->lib_dir = NULL;

	if (!_init_lvm_conf(cmd))
		return_0;

	/* Temporary duplicate cft pointer holding lvm.conf - replaced later */
	cft_tmp = cmd->cft;
	if (cft_cmdline)
		cmd->cft = dm_config_insert_cascaded_tree(cft_cmdline, cft_tmp);

	/* Reload the global profile. */
	if (profile_command_name) {
		if (!(profile = add_profile(cmd, profile_command_name, CONFIG_PROFILE_COMMAND)) ||
		    !override_config_tree_from_profile(cmd, profile))
			return_0;
	}
	if (profile_metadata_name) {
		if (!(profile = add_profile(cmd, profile_metadata_name, CONFIG_PROFILE_METADATA)) ||
		    !override_config_tree_from_profile(cmd, profile))
			return_0;
	}

	/* Uses cmd->cft i.e. cft_cmdline + lvm.conf */
	_init_logging(cmd);

	/* Init tags from lvm.conf. */
	if (!_init_tags(cmd, cft_tmp))
		return_0;

	/* Load lvmlocal.conf */
	if (*cmd->system_dir && !_load_config_file(cmd, "", 1))
		return_0;

	/* Doesn't change cmd->cft */
	if (!_init_tag_configs(cmd))
		return_0;

	/* Merge all the tag config files with lvm.conf, returning a
	 * fresh cft pointer in place of cft_tmp. */
	if (!(cmd->cft = _merge_config_files(cmd, cft_tmp)))
		return_0;

	/* Finally we can make the proper, fully-merged, cmd->cft */
	if (cft_cmdline)
		cmd->cft = dm_config_insert_cascaded_tree(cft_cmdline, cmd->cft);

	if (!_process_config(cmd))
		return_0;

	if (!_init_profiles(cmd))
		return_0;

	if (!(cmd->dev_types = create_dev_types(cmd->proc_dir,
						find_config_tree_array(cmd, devices_types_CFG, NULL))))
		return_0;

	if (!_init_dev_cache(cmd))
		return_0;

	if (!_init_formats(cmd))
		return_0;

	if (!init_lvmcache_orphans(cmd))
		return_0;

	if (!_init_segtypes(cmd))
		return_0;

	if (!_init_backup(cmd))
		return_0;

	cmd->initialized.config = 1;

	if (cmd->initialized.connections && !init_connections(cmd))
		return_0;

	if (!refresh_filters(cmd))
		return_0;

	reset_lvm_errno(1);
	return 1;
}

void destroy_toolcontext(struct cmd_context *cmd)
{
	struct dm_config_tree *cft_cmdline;
	FILE *new_stream;
	int flags;

	if (cmd->dump_filter && cmd->filter && cmd->filter->dump &&
	    !cmd->filter->dump(cmd->filter, 1))
		stack;

	archive_exit(cmd);
	backup_exit(cmd);
	lvmcache_destroy(cmd, 0, 0);
	label_exit();
	_destroy_segtypes(&cmd->segtypes);
	_destroy_formats(cmd, &cmd->formats);
	_destroy_filters(cmd);
	if (cmd->mem)
		dm_pool_destroy(cmd->mem);
	dev_cache_exit();
	_destroy_dev_types(cmd);
	_destroy_tags(cmd);

	if ((cft_cmdline = remove_config_tree_by_source(cmd, CONFIG_STRING)))
		config_destroy(cft_cmdline);
	_destroy_config(cmd);

	if (cmd->cft_def_hash)
		dm_hash_destroy(cmd->cft_def_hash);

	if (cmd->log_rh)
		dm_report_free(cmd->log_rh);

	if (cmd->libmem)
		dm_pool_destroy(cmd->libmem);

#ifndef VALGRIND_POOL
	if (cmd->linebuffer) {
		/* Reset stream buffering to defaults */
		if (is_valid_fd(STDIN_FILENO) &&
		    ((flags = fcntl(STDIN_FILENO, F_GETFL)) > 0) &&
		    (flags & O_ACCMODE) != O_WRONLY) {
			if (_reopen_stream(stdin, STDIN_FILENO, "r", "stdin", &new_stream)) {
				stdin = new_stream;
				setlinebuf(stdin);
			} else
				cmd->linebuffer = NULL;	/* Leave buffer in place (deliberate leak) */
		}

		if (is_valid_fd(STDOUT_FILENO) &&
		    ((flags = fcntl(STDOUT_FILENO, F_GETFL)) > 0) &&
		    (flags & O_ACCMODE) != O_RDONLY) {
			if (_reopen_stream(stdout, STDOUT_FILENO, "w", "stdout", &new_stream)) {
				stdout = new_stream;
				setlinebuf(stdout);
			} else
				cmd->linebuffer = NULL;	/* Leave buffer in place (deliberate leak) */
		}

		dm_free(cmd->linebuffer);
	}
#endif
	dm_free(cmd);

	lvmetad_release_token();
	lvmetad_disconnect();
	lvmpolld_disconnect();

	release_log_memory();
	activation_exit();
	reset_log_duplicated();
	fin_log();
	fin_syslog();
	reset_lvm_errno(0);
}
