/*
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2007 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 "device.h"
#include "memlock.h"
#include "lvm-string.h"
#include "defaults.h"
#include "metadata-exported.h"

#include <stdarg.h>

static int _verbose_level = VERBOSE_BASE_LEVEL;
static int _silent = 0;
static int _test = 0;
static int _md_filtering = 0;
static int _internal_filtering = 0;
static int _fwraid_filtering = 0;
static int _pvmove = 0;
static int _full_scan_done = 0;	/* Restrict to one full scan during each cmd */
static int _obtain_device_list_from_udev = DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV;
static enum dev_ext_e _external_device_info_source = DEV_EXT_NONE;
static int _trust_cache = 0; /* Don't scan when incomplete VGs encountered */
static int _debug_level = 0;
static int _debug_classes_logged = 0;
static int _log_cmd_name = 0;
static int _ignorelockingfailure = 0;
static int _security_level = SECURITY_LEVEL;
static char _cmd_name[30] = "";
static int _mirror_in_sync = 0;
static int _dmeventd_monitor = DEFAULT_DMEVENTD_MONITOR;
/* When set, disables update of _dmeventd_monitor & _ignore_suspended_devices */
static int _disable_dmeventd_monitoring = 0;
static int _background_polling = DEFAULT_BACKGROUND_POLLING;
static int _ignore_suspended_devices = 0;
static int _ignore_lvm_mirrors = DEFAULT_IGNORE_LVM_MIRRORS;
static int _error_message_produced = 0;
static unsigned _is_static = 0;
static int _udev_checking = 1;
static int _retry_deactivation = DEFAULT_RETRY_DEACTIVATION;
static int _activation_checks = 0;
static char _sysfs_dir_path[PATH_MAX] = "";
static int _dev_disable_after_error_count = DEFAULT_DISABLE_AFTER_ERROR_COUNT;
static uint64_t _pv_min_size = (DEFAULT_PV_MIN_SIZE_KB * 1024L >> SECTOR_SHIFT);
static int _detect_internal_vg_cache_corruption =
	DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION;
static const char *_unknown_device_name = DEFAULT_UNKNOWN_DEVICE_NAME;

void init_verbose(int level)
{
	_verbose_level = level;
}

void init_silent(int silent)
{
	_silent = silent;
}

void init_test(int level)
{
	if (!_test && level)
		log_warn("TEST MODE: Metadata will NOT be updated and volumes will not be (de)activated.");
	_test = level;
}

void init_md_filtering(int level)
{
	_md_filtering = level;
}

void init_internal_filtering(int level)
{
	_internal_filtering = level;
}

void init_fwraid_filtering(int level)
{
	_fwraid_filtering = level;
}

void init_pvmove(int level)
{
	_pvmove = level;
}

void init_full_scan_done(int level)
{
	_full_scan_done = level;
}

void init_obtain_device_list_from_udev(int device_list_from_udev)
{
	_obtain_device_list_from_udev = device_list_from_udev;
}

void init_external_device_info_source(enum dev_ext_e src)
{
	_external_device_info_source = src;
}

void init_trust_cache(int trustcache)
{
	_trust_cache = trustcache;
}

void init_ignorelockingfailure(int level)
{
	_ignorelockingfailure = level;
}

void init_security_level(int level)
{
	_security_level = level;
}

void init_mirror_in_sync(int in_sync)
{
	_mirror_in_sync = in_sync;
}

void init_dmeventd_monitor(int reg)
{
	if (!_disable_dmeventd_monitoring)
		_dmeventd_monitor = reg;
}

void init_disable_dmeventd_monitoring(int reg)
{
	_disable_dmeventd_monitoring = reg;
}

void init_background_polling(int polling)
{
	_background_polling = polling;
}

void init_ignore_suspended_devices(int ignore)
{
	if (!_disable_dmeventd_monitoring)
		_ignore_suspended_devices = ignore;
}

void init_ignore_lvm_mirrors(int scan)
{
	_ignore_lvm_mirrors = scan;
}

void init_cmd_name(int status)
{
	_log_cmd_name = status;
}

void init_is_static(unsigned value)
{
	_is_static = value;
}

void init_udev_checking(int checking)
{
	if ((_udev_checking = checking))
		log_debug_activation("LVM udev checking enabled");
	else
		log_debug_activation("LVM udev checking disabled");
}

void init_retry_deactivation(int retry)
{
	_retry_deactivation = retry;
}

void init_activation_checks(int checks)
{
	if ((_activation_checks = checks))
		log_debug_activation("LVM activation checks enabled");
	else
		log_debug_activation("LVM activation checks disabled");
}

void init_dev_disable_after_error_count(int value)
{
	_dev_disable_after_error_count = value;
}

void init_pv_min_size(uint64_t sectors)
{
	_pv_min_size = sectors;
}

void init_detect_internal_vg_cache_corruption(int detect)
{
	_detect_internal_vg_cache_corruption = detect;
}

void set_cmd_name(const char *cmd)
{
	strncpy(_cmd_name, cmd, sizeof(_cmd_name) - 1);
	_cmd_name[sizeof(_cmd_name) - 1] = '\0';
}

const char *get_cmd_name(void)
{
	return _cmd_name;
}

void set_sysfs_dir_path(const char *path)
{
	strncpy(_sysfs_dir_path, path, sizeof(_sysfs_dir_path) - 1);
	_sysfs_dir_path[sizeof(_sysfs_dir_path) - 1] = '\0';
}

const char *log_command_name(void)
{
	if (!_log_cmd_name)
		return "";

	return _cmd_name;
}

void init_error_message_produced(int value)
{
	_error_message_produced = value;
}

int error_message_produced(void)
{
	return _error_message_produced;
}

int test_mode(void)
{
	return _test;
}

int md_filtering(void)
{
	return _md_filtering;
}

int internal_filtering(void)
{
	return _internal_filtering;
}

int fwraid_filtering(void)
{
	return _fwraid_filtering;
}

int pvmove_mode(void)
{
	return _pvmove;
}

int full_scan_done(void)
{
	return _full_scan_done;
}

int obtain_device_list_from_udev(void)
{
	return _obtain_device_list_from_udev;
}

enum dev_ext_e external_device_info_source(void)
{
	return _external_device_info_source;
}

int trust_cache(void)
{
	return _trust_cache;
}

int background_polling(void)
{
	return _background_polling;
}

int ignorelockingfailure(void)
{
	return _ignorelockingfailure;
}

int security_level(void)
{
	return _security_level;
}

int mirror_in_sync(void)
{
	return _mirror_in_sync;
}

int dmeventd_monitor_mode(void)
{
	return _dmeventd_monitor;
}

int ignore_suspended_devices(void)
{
	return _ignore_suspended_devices;
}

int ignore_lvm_mirrors(void)
{
	return _ignore_lvm_mirrors;
}

void init_debug(int level)
{
	_debug_level = level;
}

void init_debug_classes_logged(int classes)
{
	_debug_classes_logged = classes;
}

int debug_class_is_logged(int class)
{
	/* If no class given, log it */
	if (!class)
		return 1;

	return (_debug_classes_logged & class) ? 1 : 0;
}

int verbose_level(void)
{
	return _verbose_level;
}

int debug_level(void)
{
	return _debug_level;
}

int silent_mode(void)
{
	return _silent;
}

unsigned is_static(void)
{
	return _is_static;
}

int udev_checking(void)
{
	return _udev_checking;
}

int retry_deactivation(void)
{
	return _retry_deactivation;
}

int activation_checks(void)
{
	return _activation_checks;
}

const char *sysfs_dir_path(void)
{
	return _sysfs_dir_path;
}

int dev_disable_after_error_count(void)
{
	return _dev_disable_after_error_count;
}

uint64_t pv_min_size(void)
{
	return _pv_min_size;
}

int detect_internal_vg_cache_corruption(void)
{
	return _detect_internal_vg_cache_corruption;
}

const char *unknown_device_name(void)
{
	return _unknown_device_name;
}

void init_unknown_device_name(const char *name)
{
	_unknown_device_name = name;
}

