2014-01-27 15:27:16 +04:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2014-01-27 15:27:16 +04:00
* Copyright ( C ) 2004 - 2014 Red Hat , Inc . All rights reserved .
2002-11-18 17:01:16 +03:00
*
2004-03-30 23:35:44 +04:00
* 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
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2002-11-18 17:01:16 +03:00
*/
# 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"
2002-12-12 23:55:49 +03:00
# include "display.h"
2003-07-05 02:34:56 +04:00
# include "memlock.h"
2004-03-08 21:13:22 +03:00
# include "str_list.h"
2004-09-16 22:40:56 +04:00
# include "segtype.h"
2004-05-05 01:25:57 +04:00
# include "lvmcache.h"
2012-02-23 17:11:07 +04:00
# include "lvmetad.h"
2005-05-17 17:46:38 +04:00
# include "archiver.h"
2015-05-09 02:59:18 +03:00
# include "lvmpolld-client.h"
2002-11-18 17:01:16 +03:00
2003-03-24 21:08:53 +03:00
# ifdef HAVE_LIBDL
# include "sharedlib.h"
# endif
2002-11-18 17:01:16 +03:00
# include <locale.h>
# include <sys/stat.h>
2018-02-09 02:26:22 +03:00
# include <sys/syscall.h>
2004-03-08 20:25:59 +03:00
# include <sys/utsname.h>
2002-11-18 17:01:16 +03:00
# include <syslog.h>
# include <time.h>
2013-11-13 17:56:29 +04:00
# ifdef __linux__
2003-07-05 02:34:56 +04:00
# include <malloc.h>
# endif
2017-10-18 17:57:46 +03:00
static const size_t _linebuffer_size = 4096 ;
2011-05-07 17:50:11 +04:00
2015-02-23 23:36:27 +03:00
/*
* Copy the input string , removing invalid characters .
*/
2015-02-24 02:03:52 +03:00
const char * system_id_from_string ( struct cmd_context * cmd , const char * str )
2014-10-24 21:29:04 +04:00
{
char * system_id ;
2015-02-25 17:12:24 +03:00
if ( ! str | | ! * str ) {
log_warn ( " WARNING: Empty system ID supplied. " ) ;
return " " ;
}
2015-03-19 02:25:30 +03:00
if ( ! ( system_id = dm_pool_zalloc ( cmd - > libmem , strlen ( str ) + 1 ) ) ) {
2015-02-23 23:36:27 +03:00
log_warn ( " WARNING: Failed to allocate system ID. " ) ;
2014-10-24 21:29:04 +04:00
return NULL ;
2015-02-23 23:36:27 +03:00
}
2014-10-24 21:29:04 +04:00
2015-02-23 22:47:03 +03:00
copy_systemid_chars ( str , system_id ) ;
2014-10-24 21:29:04 +04:00
2015-02-23 23:36:27 +03:00
if ( ! * system_id ) {
log_warn ( " WARNING: Invalid system ID format: %s " , str ) ;
2014-10-24 21:29:04 +04:00
return NULL ;
2015-02-23 23:36:27 +03:00
}
if ( ! strncmp ( system_id , " localhost " , 9 ) ) {
2015-02-27 22:32:00 +03:00
log_warn ( " WARNING: system ID may not begin with the string \" localhost \" . " ) ;
2015-02-23 23:36:27 +03:00
return NULL ;
}
2014-10-24 21:29:04 +04:00
return system_id ;
}
2015-02-24 02:03:52 +03:00
static const char * _read_system_id_from_file ( struct cmd_context * cmd , const char * file )
2014-10-24 21:29:04 +04:00
{
2015-02-23 23:49:15 +03:00
char * line = NULL ;
size_t line_size ;
char * start , * end ;
2015-02-24 02:03:52 +03:00
const char * system_id = NULL ;
2014-10-24 21:29:04 +04:00
FILE * fp ;
if ( ! file | | ! strlen ( file ) | | ! file [ 0 ] )
2015-02-23 23:49:15 +03:00
return_NULL ;
2014-10-24 21:29:04 +04:00
2015-02-13 20:37:11 +03:00
if ( ! ( fp = fopen ( file , " r " ) ) ) {
2015-02-23 23:49:15 +03:00
log_warn ( " WARNING: %s: fopen failed: %s " , file , strerror ( errno ) ) ;
2014-10-24 21:29:04 +04:00
return NULL ;
2015-02-13 20:37:11 +03:00
}
2014-10-24 21:29:04 +04:00
2015-02-23 23:49:15 +03:00
while ( getline ( & line , & line_size , fp ) > 0 ) {
start = line ;
2014-10-24 21:29:04 +04:00
2015-02-23 23:49:15 +03:00
/* Ignore leading whitespace */
while ( * start & & isspace ( * start ) )
start + + ;
/* Ignore rest of line after # */
if ( ! * start | | * start = = ' # ' )
2014-10-24 21:29:04 +04:00
continue ;
2015-02-25 17:12:24 +03:00
if ( system_id & & * system_id ) {
2015-02-23 23:49:15 +03:00
log_warn ( " WARNING: Ignoring extra line(s) in system ID file %s. " , file ) ;
break ;
}
/* Remove any comments from end of line */
2015-02-25 17:12:24 +03:00
for ( end = start ; * end ; end + + )
2015-02-23 23:49:15 +03:00
if ( * end = = ' # ' ) {
* end = ' \0 ' ;
break ;
}
system_id = system_id_from_string ( cmd , start ) ;
2014-10-24 21:29:04 +04:00
}
2015-02-23 23:49:15 +03:00
free ( line ) ;
2015-02-13 20:37:11 +03:00
if ( fclose ( fp ) )
stack ;
2015-02-23 23:49:15 +03:00
return system_id ;
2014-10-24 21:29:04 +04:00
}
2015-02-24 02:03:52 +03:00
static const char * _system_id_from_source ( struct cmd_context * cmd , const char * source )
2014-10-24 21:29:04 +04:00
{
char filebuf [ PATH_MAX ] ;
const char * file ;
const char * etc_str ;
const char * str ;
2015-02-24 02:03:52 +03:00
const char * system_id = NULL ;
2014-10-24 21:29:04 +04:00
2015-02-23 23:36:27 +03:00
if ( ! strcasecmp ( source , " uname " ) ) {
if ( cmd - > hostname )
system_id = system_id_from_string ( cmd , cmd - > hostname ) ;
2014-10-24 21:29:04 +04:00
goto out ;
}
/* lvm.conf and lvmlocal.conf are merged into one config tree */
2015-02-23 23:36:27 +03:00
if ( ! strcasecmp ( source , " lvmlocal " ) ) {
2014-10-24 21:29:04 +04:00
if ( ( str = find_config_tree_str ( cmd , local_system_id_CFG , NULL ) ) )
system_id = system_id_from_string ( cmd , str ) ;
goto out ;
}
2015-02-23 23:36:27 +03:00
if ( ! strcasecmp ( source , " machineid " ) | | ! strcasecmp ( source , " machine-id " ) ) {
2014-10-24 21:29:04 +04:00
etc_str = find_config_tree_str ( cmd , global_etc_CFG , NULL ) ;
2015-02-23 23:36:27 +03:00
if ( dm_snprintf ( filebuf , sizeof ( filebuf ) , " %s/machine-id " , etc_str ) ! = - 1 )
2014-10-24 21:29:04 +04:00
system_id = _read_system_id_from_file ( cmd , filebuf ) ;
goto out ;
}
2015-02-23 23:36:27 +03:00
if ( ! strcasecmp ( source , " file " ) ) {
2014-10-24 21:29:04 +04:00
file = find_config_tree_str ( cmd , global_system_id_file_CFG , NULL ) ;
system_id = _read_system_id_from_file ( cmd , file ) ;
goto out ;
}
2015-02-23 23:36:27 +03:00
log_warn ( " WARNING: Unrecognised system_id_source \" %s \" . " , source ) ;
2014-10-24 21:29:04 +04:00
out :
return system_id ;
}
2002-11-18 17:01:16 +03:00
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 " ) ) ) {
2009-02-23 00:14:37 +03:00
if ( dm_snprintf ( cmd - > system_dir , sizeof ( cmd - > system_dir ) ,
2002-11-18 17:01:16 +03:00
" %s " , e ) < 0 ) {
log_error ( " LVM_SYSTEM_DIR environment variable "
" is too long. " ) ;
return 0 ;
}
}
2017-01-23 16:24:27 +03:00
if ( strcmp ( ( getenv ( " LVM_RUN_BY_DMEVENTD " ) ? : " 0 " ) , " 1 " ) = = 0 )
init_run_by_dmeventd ( cmd ) ;
2002-11-18 17:01:16 +03:00
return 1 ;
}
2013-06-12 13:38:48 +04:00
static void _get_sysfs_dir ( struct cmd_context * cmd , char * buf , size_t buf_size )
2008-09-19 07:42:37 +04:00
{
static char proc_mounts [ PATH_MAX ] ;
static char * split [ 4 ] , buffer [ PATH_MAX + 16 ] ;
FILE * fp ;
char * sys_mnt = NULL ;
2013-06-12 13:38:48 +04:00
* buf = ' \0 ' ;
2008-09-19 07:42:37 +04:00
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 " ) ) ) {
2012-01-12 00:38:42 +04:00
log_sys_error ( " _get_sysfs_dir fopen " , proc_mounts ) ;
2008-09-19 07:42:37 +04:00
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 ;
}
2013-06-12 13:38:48 +04:00
strncpy ( buf , sys_mnt , buf_size ) ;
2008-09-19 07:42:37 +04:00
}
2013-01-08 02:25:19 +04:00
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 ;
2015-07-15 11:52:23 +03:00
if ( ! ( cn = find_config_tree_array ( cmd , log_debug_classes_CFG , NULL ) ) ) {
log_error ( INTERNAL_ERROR " Unable to find configuration for log/debug_classes. " ) ;
2015-07-08 12:22:24 +03:00
return - 1 ;
2015-07-15 11:52:23 +03:00
}
2013-01-08 02:25:19 +04:00
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 ;
2015-05-12 16:26:26 +03:00
else if ( ! strcasecmp ( cv - > v . str , " lvmpolld " ) )
debug_classes | = LOG_CLASS_LVMPOLLD ;
2016-02-22 18:42:03 +03:00
else if ( ! strcasecmp ( cv - > v . str , " dbus " ) )
debug_classes | = LOG_CLASS_DBUS ;
2017-11-15 03:59:30 +03:00
else if ( ! strcasecmp ( cv - > v . str , " io " ) )
debug_classes | = LOG_CLASS_IO ;
2013-01-08 02:25:19 +04:00
else
log_verbose ( " Unrecognised value for log/debug_classes: %s " , cv - > v . str ) ;
}
return debug_classes ;
}
2002-11-18 17:01:16 +03:00
static void _init_logging ( struct cmd_context * cmd )
{
2003-07-05 02:34:56 +04:00
int append = 1 ;
2002-11-18 17:01:16 +03:00
time_t t ;
const char * log_file ;
2006-05-16 20:48:31 +04:00
char timebuf [ 26 ] ;
2002-11-18 17:01:16 +03:00
/* Syslog */
2013-06-25 14:31:53 +04:00
cmd - > default_settings . syslog = find_config_tree_bool ( cmd , log_syslog_CFG , NULL ) ;
2002-11-18 17:01:16 +03:00
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 */
2013-06-25 14:30:34 +04:00
cmd - > default_settings . debug = find_config_tree_int ( cmd , log_level_CFG , NULL ) ;
2002-11-18 17:01:16 +03:00
init_debug ( cmd - > default_settings . debug ) ;
2012-08-26 03:15:45 +04:00
/*
* 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 ( ) ? :
2013-06-25 14:31:53 +04:00
find_config_tree_bool ( cmd , log_silent_CFG , NULL ) ;
config: add silent mode
Accept -q as the short form of --quiet.
Suppress non-essential standard output if -q is given twice.
Treat log/silent in lvm.conf as equivalent to -qq.
Review all log_print messages and change some to
log_print_unless_silent.
When silent, the following commands still produce output:
dumpconfig, lvdisplay, lvmdiskscan, lvs, pvck, pvdisplay,
pvs, version, vgcfgrestore -l, vgdisplay, vgs.
[Needs checking.]
Non-essential messages are shifted from log level 4 to log level 5
for syslog and lvm2_log_fn purposes.
2012-08-25 23:35:48 +04:00
init_silent ( cmd - > default_settings . silent ) ;
2002-11-18 17:01:16 +03:00
/* Verbose level for tty output */
2016-01-27 14:11:03 +03:00
cmd - > default_settings . verbose = find_config_tree_int ( cmd , log_verbose_CFG , NULL ) ;
2004-03-26 14:45:01 +03:00
init_verbose ( cmd - > default_settings . verbose + VERBOSE_BASE_LEVEL ) ;
2002-11-18 17:01:16 +03:00
/* Log message formatting */
2013-06-25 14:31:53 +04:00
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 ) ) ;
2011-10-29 00:06:49 +04:00
2013-06-25 14:30:08 +04:00
cmd - > default_settings . msg_prefix = find_config_tree_str_allow_empty ( cmd , log_prefix_CFG , NULL ) ;
2002-11-18 17:01:16 +03:00
init_msg_prefix ( cmd - > default_settings . msg_prefix ) ;
2013-06-25 14:31:53 +04:00
cmd - > default_settings . cmd_name = find_config_tree_bool ( cmd , log_command_names_CFG , NULL ) ;
2002-11-18 17:01:16 +03:00
init_cmd_name ( cmd - > default_settings . cmd_name ) ;
/* Test mode */
cmd - > default_settings . test =
2013-06-25 14:31:53 +04:00
find_config_tree_bool ( cmd , global_test_CFG , NULL ) ;
2008-12-11 06:31:47 +03:00
init_test ( cmd - > default_settings . test ) ;
2002-11-18 17:01:16 +03:00
/* Settings for logging to file */
2013-06-25 14:31:53 +04:00
if ( find_config_tree_bool ( cmd , log_overwrite_CFG , NULL ) )
2003-07-05 02:34:56 +04:00
append = 0 ;
2002-11-18 17:01:16 +03:00
2013-06-25 14:29:54 +04:00
log_file = find_config_tree_str ( cmd , log_file_CFG , NULL ) ;
2004-03-08 21:13:22 +03:00
if ( log_file ) {
release_log_memory ( ) ;
fin_log ( ) ;
2003-07-05 02:34:56 +04:00
init_log_file ( log_file , append ) ;
2004-03-08 21:13:22 +03:00
}
2003-07-05 02:34:56 +04:00
2013-06-25 14:29:54 +04:00
log_file = find_config_tree_str ( cmd , log_activate_file_CFG , NULL ) ;
2003-07-05 02:34:56 +04:00
if ( log_file )
init_log_direct ( log_file , append ) ;
2013-06-25 14:31:53 +04:00
init_log_while_suspended ( find_config_tree_bool ( cmd , log_activation_CFG , NULL ) ) ;
2002-11-18 17:01:16 +03:00
2013-01-08 02:25:19 +04:00
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 ) ;
2002-11-18 17:01:16 +03:00
t = time ( NULL ) ;
2006-05-16 20:48:31 +04:00
ctime_r ( & t , & timebuf [ 0 ] ) ;
timebuf [ 24 ] = ' \0 ' ;
log_verbose ( " Logging initialised at %s " , timebuf ) ;
2002-11-18 17:01:16 +03:00
/* Tell device-mapper about our logging */
2003-01-09 01:44:07 +03:00
# ifdef DEVMAPPER_SUPPORT
2015-10-09 22:38:50 +03:00
if ( ! dm_log_is_non_default ( ) )
2016-06-23 14:55:39 +03:00
dm_log_with_errno_init ( print_log_libdm ) ;
2003-01-09 01:44:07 +03:00
# endif
2010-05-06 02:37:52 +04:00
reset_log_duplicated ( ) ;
2010-06-02 01:46:29 +04:00
reset_lvm_errno ( 1 ) ;
2002-11-18 17:01:16 +03:00
}
2012-11-29 18:50:52 +04:00
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 ;
}
2014-05-19 15:23:12 +04:00
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 ) ;
}
2013-06-26 16:53:57 +04:00
static int _check_config ( struct cmd_context * cmd )
{
2014-05-19 15:23:12 +04:00
int abort_on_error ;
2013-06-26 16:53:57 +04:00
if ( ! find_config_tree_bool ( cmd , config_checks_CFG , NULL ) )
return 1 ;
2014-05-19 15:23:12 +04:00
abort_on_error = find_config_tree_bool ( cmd , config_abort_on_errors_CFG , NULL ) ;
2013-06-26 16:53:57 +04:00
2014-05-19 15:23:12 +04:00
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. " ) ;
2013-06-26 16:53:57 +04:00
return 0 ;
}
return 1 ;
}
2015-05-25 17:13:07 +03:00
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 + + ) {
2015-06-29 15:45:45 +03:00
if ( c = = chars_to_check [ i ] )
2015-05-25 17:13:07 +03:00
break ;
}
2015-06-29 15:45:45 +03:00
if ( ! chars_to_check [ i ] )
2015-05-25 17:13:07 +03:00
goto_bad ;
}
else if ( isprint ( c ) )
p_fmt + + ;
else {
log_error ( " Configured time format contains non-printable characters. " ) ;
goto bad ;
}
}
}
return tf ;
bad :
2015-06-29 17:16:58 +03:00
log_error ( " Invalid time format \" %s \" supplied. " , tf ) ;
return NULL ;
2015-05-25 17:13:07 +03:00
}
2015-02-23 23:11:00 +03:00
int process_profilable_config ( struct cmd_context * cmd )
{
2017-07-27 02:51:50 +03:00
const char * units ;
2014-03-17 19:03:53 +04:00
if ( ! ( cmd - > default_settings . unit_factor =
2017-07-27 02:51:50 +03:00
dm_units_to_factor ( units = find_config_tree_str ( cmd , global_units_CFG , NULL ) ,
2014-04-28 12:25:43 +04:00
& cmd - > default_settings . unit_type , 1 , NULL ) ) ) {
2017-07-27 02:51:50 +03:00
log_error ( " Unrecognised configuration setting for global/units: %s " , units ) ;
2014-03-17 19:03:53 +04:00
return 0 ;
}
cmd - > si_unit_consistency = find_config_tree_bool ( cmd , global_si_unit_consistency_CFG , NULL ) ;
2014-07-02 15:16:32 +04:00
cmd - > report_binary_values_as_numeric = find_config_tree_bool ( cmd , report_binary_values_as_numeric_CFG , NULL ) ;
2016-01-13 17:21:05 +03:00
cmd - > report_mark_hidden_devices = find_config_tree_bool ( cmd , report_mark_hidden_devices_CFG , NULL ) ;
2014-03-18 12:24:17 +04:00
cmd - > default_settings . suffix = find_config_tree_bool ( cmd , global_suffix_CFG , NULL ) ;
2014-07-10 18:18:45 +04:00
cmd - > report_list_item_separator = find_config_tree_str ( cmd , report_list_item_separator_CFG , NULL ) ;
2015-06-29 17:16:58 +03:00
if ( ! ( cmd - > time_format = _set_time_format ( cmd ) ) )
return 0 ;
2014-03-17 19:03:53 +04:00
return 1 ;
}
2015-02-23 23:21:00 +03:00
static int _init_system_id ( struct cmd_context * cmd )
{
2015-02-24 00:20:51 +03:00
const char * source , * system_id ;
int local_set = 0 ;
2015-02-23 23:21:00 +03:00
cmd - > system_id = NULL ;
2015-02-24 00:20:51 +03:00
cmd - > unknown_system_id = 0 ;
2015-02-23 23:21:00 +03:00
2015-02-24 00:20:51 +03:00
system_id = find_config_tree_str_allow_empty ( cmd , local_system_id_CFG , NULL ) ;
if ( system_id & & * system_id )
local_set = 1 ;
2015-02-23 23:21:00 +03:00
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 ;
2015-02-25 17:12:24 +03:00
if ( ( system_id = _system_id_from_source ( cmd , source ) ) & & * system_id ) {
cmd - > system_id = system_id ;
2015-02-23 23:21:00 +03:00
return 1 ;
2015-02-25 17:12:24 +03:00
}
2015-02-23 23:21:00 +03:00
/*
* 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 .
*/
2015-02-27 22:32:00 +03:00
log_warn ( " WARNING: No system ID found from system_id_source %s. " , source ) ;
2015-02-23 23:21:00 +03:00
cmd - > unknown_system_id = 1 ;
return 1 ;
}
2002-11-18 17:01:16 +03:00
static int _process_config ( struct cmd_context * cmd )
{
mode_t old_umask ;
2014-12-15 18:27:33 +03:00
const char * dev_ext_info_src ;
2007-11-09 19:51:54 +03:00
const char * read_ahead ;
2008-09-19 10:42:00 +04:00
struct stat st ;
2011-08-30 18:55:15 +04:00
const struct dm_config_node * cn ;
const struct dm_config_value * cv ;
2011-02-18 17:11:22 +03:00
int64_t pv_min_kb ;
2012-11-29 17:03:48 +04:00
int udev_disabled = 0 ;
2013-06-12 13:38:48 +04:00
char sysfs_dir [ PATH_MAX ] ;
2002-11-18 17:01:16 +03:00
2013-06-26 16:53:57 +04:00
if ( ! _check_config ( cmd ) )
return_0 ;
2013-03-05 20:36:10 +04:00
2002-11-18 17:01:16 +03:00
/* umask */
2013-06-25 14:30:34 +04:00
cmd - > default_settings . umask = find_config_tree_int ( cmd , global_umask_CFG , NULL ) ;
2002-11-18 17:01:16 +03:00
if ( ( old_umask = umask ( ( mode_t ) cmd - > default_settings . umask ) ) ! =
( mode_t ) cmd - > default_settings . umask )
2010-12-20 17:34:49 +03:00
log_verbose ( " Set umask from %04o to %04o " ,
old_umask , cmd - > default_settings . umask ) ;
2002-11-18 17:01:16 +03:00
/* dev dir */
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( cmd - > dev_dir , sizeof ( cmd - > dev_dir ) , " %s/ " ,
2013-06-25 14:29:54 +04:00
find_config_tree_str ( cmd , devices_dir_CFG , NULL ) ) < 0 ) {
2002-11-18 17:01:16 +03:00
log_error ( " Device directory given in config file too long " ) ;
return 0 ;
}
2003-01-09 01:44:07 +03:00
# ifdef DEVMAPPER_SUPPORT
2002-11-18 17:01:16 +03:00
dm_set_dev_dir ( cmd - > dev_dir ) ;
2012-01-10 06:03:31 +04:00
2017-12-04 16:26:37 +03:00
if ( ! dm_set_uuid_prefix ( UUID_PREFIX ) )
2012-01-10 06:03:31 +04:00
return_0 ;
2003-01-09 01:44:07 +03:00
# endif
2002-11-18 17:01:16 +03:00
2014-12-15 18:27:33 +03:00
dev_ext_info_src = find_config_tree_str ( cmd , devices_external_device_info_source_CFG , NULL ) ;
2015-11-09 18:58:24 +03:00
if ( dev_ext_info_src & & ! strcmp ( dev_ext_info_src , " none " ) )
2014-12-15 18:27:33 +03:00
init_external_device_info_source ( DEV_EXT_NONE ) ;
2015-11-09 18:58:24 +03:00
else if ( dev_ext_info_src & & ! strcmp ( dev_ext_info_src , " udev " ) )
2014-12-15 18:27:33 +03:00
init_external_device_info_source ( DEV_EXT_UDEV ) ;
else {
log_error ( " Invalid external device info source specification. " ) ;
return 0 ;
}
2002-11-18 17:01:16 +03:00
/* proc dir */
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( cmd - > proc_dir , sizeof ( cmd - > proc_dir ) , " %s " ,
2013-06-25 14:29:54 +04:00
find_config_tree_str ( cmd , global_proc_CFG , NULL ) ) < 0 ) {
2002-11-18 17:01:16 +03:00
log_error ( " Device directory given in config file too long " ) ;
return 0 ;
}
2005-01-27 18:50:34 +03:00
if ( * cmd - > proc_dir & & ! dir_exists ( cmd - > proc_dir ) ) {
2010-04-01 14:34:09 +04:00
log_warn ( " WARNING: proc dir %s not found - some checks will be bypassed " ,
cmd - > proc_dir ) ;
2005-01-27 18:50:34 +03:00
cmd - > proc_dir [ 0 ] = ' \0 ' ;
}
2013-06-12 13:38:48 +04:00
_get_sysfs_dir ( cmd , sysfs_dir , sizeof ( sysfs_dir ) ) ;
dm_set_sysfs_dir ( sysfs_dir ) ;
2008-09-19 07:42:37 +04:00
2002-11-18 17:01:16 +03:00
/* activation? */
2013-06-25 14:31:53 +04:00
cmd - > default_settings . activation = find_config_tree_bool ( cmd , global_activation_CFG , NULL ) ;
2014-04-18 05:46:34 +04:00
set_activation ( cmd - > default_settings . activation , 0 ) ;
2002-11-18 17:01:16 +03:00
2013-07-12 11:27:17 +04:00
cmd - > auto_set_activation_skip = find_config_tree_bool ( cmd , activation_auto_set_activation_skip_CFG , NULL ) ;
2013-06-25 14:29:54 +04:00
read_ahead = find_config_tree_str ( cmd , activation_readahead_CFG , NULL ) ;
2007-11-09 19:51:54 +03:00
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 ;
2002-12-12 23:55:49 +03:00
}
2012-11-29 17:03:48 +04:00
/*
* 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
*/
2012-11-29 18:50:52 +04:00
udev_disabled = _check_disable_udev ( " manage logical volume symlinks in device directory " ) ;
2012-11-29 17:03:48 +04:00
cmd - > default_settings . udev_rules = udev_disabled ? 0 :
2013-06-25 14:31:53 +04:00
find_config_tree_bool ( cmd , activation_udev_rules_CFG , NULL ) ;
2010-01-07 22:54:21 +03:00
2012-11-29 17:03:48 +04:00
cmd - > default_settings . udev_sync = udev_disabled ? 0 :
2013-06-25 14:31:53 +04:00
find_config_tree_bool ( cmd , activation_udev_sync_CFG , NULL ) ;
2009-08-04 19:36:13 +04:00
2011-06-17 18:50:53 +04:00
/*
2013-05-13 13:46:24 +04:00
* 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 .
2011-06-17 18:50:53 +04:00
*/
2013-05-13 13:46:24 +04:00
cmd - > default_settings . udev_fallback = udev_disabled ? 1 : - 1 ;
2011-07-08 20:49:04 +04:00
2013-06-25 14:31:53 +04:00
init_retry_deactivation ( find_config_tree_bool ( cmd , activation_retry_deactivation_CFG , NULL ) ) ;
2013-05-13 13:46:24 +04:00
2013-06-25 14:31:53 +04:00
init_activation_checks ( find_config_tree_bool ( cmd , activation_checks_CFG , NULL ) ) ;
2011-06-17 18:50:53 +04:00
2013-06-25 14:31:53 +04:00
cmd - > use_linear_target = find_config_tree_bool ( cmd , activation_use_linear_target_CFG , NULL ) ;
2011-11-29 00:37:51 +04:00
2013-06-25 14:29:54 +04:00
cmd - > stripe_filler = find_config_tree_str ( cmd , activation_missing_stripe_filler_CFG , NULL ) ;
2008-09-19 22:26:41 +04:00
/* 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 " ;
2016-10-18 13:58:22 +03:00
else if ( strcmp ( cmd - > stripe_filler , " error " ) & &
strcmp ( cmd - > stripe_filler , " zero " ) ) {
2008-09-19 10:42:00 +04:00
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 " ;
}
}
2015-07-08 12:22:24 +03:00
if ( ( cn = find_config_tree_array ( cmd , activation_mlock_filter_CFG , NULL ) ) )
2010-03-09 06:16:11 +03:00
for ( cv = cn - > v ; cv ; cv = cv - > next )
2011-08-30 18:55:15 +04:00
if ( ( cv - > type ! = DM_CFG_STRING ) | | ! cv - > v . str [ 0 ] )
2010-03-09 06:16:11 +03:00
log_error ( " Ignoring invalid activation/mlock_filter entry in config file " ) ;
2013-06-25 14:31:53 +04:00
cmd - > metadata_read_only = find_config_tree_bool ( cmd , global_metadata_read_only_CFG , NULL ) ;
2010-10-25 15:20:54 +04:00
2013-06-25 14:31:24 +04:00
pv_min_kb = find_config_tree_int64 ( cmd , devices_pv_min_size_CFG , NULL ) ;
2012-02-01 17:42:18 +04:00
if ( pv_min_kb < PV_MIN_SIZE_KB ) {
2011-02-18 17:11:22 +03:00
log_warn ( " Ignoring too small pv_min_size % " PRId64 " KB, using default %dKB. " ,
2012-02-01 17:42:18 +04:00
pv_min_kb , PV_MIN_SIZE_KB ) ;
pv_min_kb = PV_MIN_SIZE_KB ;
2011-02-18 17:11:22 +03:00
}
2011-04-28 21:33:34 +04:00
/* LVM stores sizes internally in units of 512-byte sectors. */
2011-02-18 17:11:22 +03:00
init_pv_min_size ( ( uint64_t ) pv_min_kb * ( 1024 > > SECTOR_SHIFT ) ) ;
2016-01-22 15:20:21 +03:00
cmd - > check_pv_dev_sizes = find_config_tree_bool ( cmd , metadata_check_pv_device_sizes_CFG , NULL ) ;
2014-03-17 19:03:53 +04:00
if ( ! process_profilable_config ( cmd ) )
return_0 ;
2016-02-29 22:38:31 +03:00
if ( find_config_tree_bool ( cmd , report_two_word_unknown_device_CFG , NULL ) )
init_unknown_device_name ( " unknown device " ) ;
2015-02-23 23:21:00 +03:00
if ( ! _init_system_id ( cmd ) )
return_0 ;
2002-11-18 17:01:16 +03:00
return 1 ;
}
2004-05-04 22:28:15 +04:00
static int _set_tag ( struct cmd_context * cmd , const char * tag )
2002-11-18 17:01:16 +03:00
{
2005-10-17 03:03:59 +04:00
log_very_verbose ( " Setting host tag: %s " , dm_pool_strdup ( cmd - > libmem , tag ) ) ;
2002-11-18 17:01:16 +03:00
2004-05-04 22:28:15 +04:00
if ( ! str_list_add ( cmd - > libmem , & cmd - > tags , tag ) ) {
log_error ( " _set_tag: str_list_add %s failed " , tag ) ;
2002-11-18 17:01:16 +03:00
return 0 ;
}
2004-05-04 22:28:15 +04:00
return 1 ;
}
2011-08-30 18:55:15 +04:00
static int _check_host_filters ( struct cmd_context * cmd , const struct dm_config_node * hn ,
2004-05-04 22:28:15 +04:00
int * passes )
{
2011-08-30 18:55:15 +04:00
const struct dm_config_node * cn ;
const struct dm_config_value * cv ;
2004-05-04 22:28:15 +04:00
* passes = 1 ;
for ( cn = hn ; cn ; cn = cn - > sib ) {
if ( ! cn - > v )
continue ;
if ( ! strcmp ( cn - > key , " host_list " ) ) {
* passes = 0 ;
2011-08-30 18:55:15 +04:00
if ( cn - > v - > type = = DM_CFG_EMPTY_ARRAY )
2004-05-04 22:28:15 +04:00
continue ;
for ( cv = cn - > v ; cv ; cv = cv - > next ) {
2011-08-30 18:55:15 +04:00
if ( cv - > type ! = DM_CFG_STRING ) {
2004-05-04 22:28:15 +04:00
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 ;
}
2011-08-30 18:55:15 +04:00
static int _init_tags ( struct cmd_context * cmd , struct dm_config_tree * cft )
2004-05-04 22:28:15 +04:00
{
2011-08-30 18:55:15 +04:00
const struct dm_config_node * tn , * cn ;
2004-05-04 22:28:15 +04:00
const char * tag ;
int passes ;
2015-02-23 20:40:58 +03:00
/* Access tags section directly */
if ( ! ( tn = find_config_node ( cmd , cft , tags_CFG_SECTION ) ) | | ! tn - > child )
2002-11-18 17:01:16 +03:00
return 1 ;
2004-05-04 22:28:15 +04:00
/* NB hosttags 0 when already 1 intentionally does not delete the tag */
2015-02-23 20:40:58 +03:00
if ( ! cmd - > hosttags & & find_config_bool ( cmd , cft , tags_hosttags_CFG ) ) {
2004-05-04 22:28:15 +04:00
/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
2008-01-30 16:19:47 +03:00
if ( ! _set_tag ( cmd , cmd - > hostname ) )
return_0 ;
2004-05-04 22:28:15 +04:00
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 ;
2008-01-30 16:19:47 +03:00
if ( ! _check_host_filters ( cmd , cn - > child , & passes ) )
return_0 ;
2004-05-04 22:28:15 +04:00
if ( ! passes )
continue ;
}
2008-01-30 16:19:47 +03:00
if ( ! _set_tag ( cmd , tag ) )
return_0 ;
2004-05-04 22:28:15 +04:00
}
return 1 ;
}
2014-10-24 21:29:04 +04:00
static int _load_config_file ( struct cmd_context * cmd , const char * tag , int local )
2004-05-04 22:28:15 +04:00
{
2011-11-18 23:31:09 +04:00
static char config_file [ PATH_MAX ] = " " ;
2004-05-04 22:28:15 +04:00
const char * filler = " " ;
struct config_tree_list * cfl ;
if ( * tag )
filler = " _ " ;
2014-10-24 21:29:04 +04:00
else if ( local ) {
filler = " " ;
tag = " local " ;
}
2004-05-04 22:28:15 +04:00
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( config_file , sizeof ( config_file ) , " %s/lvm%s%s.conf " ,
2009-02-23 00:14:37 +03:00
cmd - > system_dir , filler , tag ) < 0 ) {
2004-05-04 22:28:15 +04:00
log_error ( " LVM_SYSTEM_DIR or tag was too long " ) ;
return 0 ;
}
2005-10-17 03:03:59 +04:00
if ( ! ( cfl = dm_pool_alloc ( cmd - > libmem , sizeof ( * cfl ) ) ) ) {
2004-05-04 22:28:15 +04:00
log_error ( " config_tree_list allocation failed " ) ;
return 0 ;
}
2014-05-19 15:23:12 +04:00
if ( ! ( cfl - > cft = config_file_open_and_read ( config_file , CONFIG_FILE , cmd ) ) )
2013-06-25 14:25:23 +04:00
return_0 ;
2002-11-18 17:01:16 +03:00
2008-11-04 01:14:30 +03:00
dm_list_add ( & cmd - > config_files , & cfl - > list ) ;
2004-05-04 22:28:15 +04:00
2012-02-27 14:05:35 +04:00
if ( * tag ) {
if ( ! _init_tags ( cmd , cfl - > cft ) )
return_0 ;
} else
2004-05-04 22:28:15 +04:00
/* Use temporary copy of lvm.conf while loading other files */
cmd - > cft = cfl - > cft ;
return 1 ;
}
2014-10-24 21:29:04 +04:00
/*
2015-02-23 23:11:00 +03:00
* Find and read lvm . conf .
2014-10-24 21:29:04 +04:00
*/
2004-05-04 22:28:15 +04:00
static int _init_lvm_conf ( struct cmd_context * cmd )
{
/* No config file if LVM_SYSTEM_DIR is empty */
2009-02-23 00:14:37 +03:00
if ( ! * cmd - > system_dir ) {
2013-06-25 14:25:43 +04:00
if ( ! ( cmd - > cft = config_open ( CONFIG_FILE , NULL , 0 ) ) ) {
2004-05-04 22:28:15 +04:00
log_error ( " Failed to create config tree " ) ;
return 0 ;
}
return 1 ;
}
2014-10-24 21:29:04 +04:00
if ( ! _load_config_file ( cmd , " " , 0 ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2004-05-04 22:28:15 +04:00
return 1 ;
}
/* Read any additional config files */
static int _init_tag_configs ( struct cmd_context * cmd )
{
2014-05-29 11:41:03 +04:00
struct dm_str_list * sl ;
2004-05-04 22:28:15 +04:00
/* Tag list may grow while inside this loop */
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( sl , & cmd - > tags ) {
2014-10-24 21:29:04 +04:00
if ( ! _load_config_file ( cmd , sl - > str , 0 ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2004-05-04 22:28:15 +04:00
}
2002-11-18 17:01:16 +03:00
return 1 ;
}
2013-06-25 14:27:04 +04:00
static int _init_profiles ( struct cmd_context * cmd )
{
const char * dir ;
2014-03-03 16:30:13 +04:00
if ( ! ( dir = find_config_tree_str ( cmd , config_profile_dir_CFG , NULL ) ) )
return_0 ;
2013-06-25 14:27:04 +04:00
2014-06-19 13:30:57 +04:00
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 ) ;
2014-05-19 15:59:23 +04:00
}
2013-06-25 14:27:04 +04:00
2014-06-24 16:58:53 +04:00
if ( ! ( dm_strncpy ( cmd - > profile_params - > dir , dir , sizeof ( cmd - > profile_params - > dir ) ) ) ) {
log_error ( " _init_profiles: dm_strncpy failed " ) ;
return 0 ;
}
2014-06-19 13:30:57 +04:00
2013-06-25 14:27:04 +04:00
return 1 ;
}
2011-09-02 16:38:43 +04:00
static struct dm_config_tree * _merge_config_files ( struct cmd_context * cmd , struct dm_config_tree * cft )
2004-05-04 22:28:15 +04:00
{
struct config_tree_list * cfl ;
/* Replace temporary duplicate copy of lvm.conf */
2011-09-02 05:32:08 +04:00
if ( cft - > root ) {
2013-06-25 14:25:43 +04:00
if ( ! ( cft = config_open ( CONFIG_MERGED_FILES , NULL , 0 ) ) ) {
2004-05-04 22:28:15 +04:00
log_error ( " Failed to create config tree " ) ;
return 0 ;
}
}
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( cfl , & cmd - > config_files ) {
2004-05-04 22:28:15 +04:00
/* Merge all config trees into cmd->cft using merge/tag rules */
2013-07-08 16:31:44 +04:00
if ( ! merge_config_tree ( cmd , cft , cfl - > cft , CONFIG_MERGE_TYPE_TAGS ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2004-05-04 22:28:15 +04:00
}
2011-09-02 05:32:08 +04:00
return cft ;
2004-05-04 22:28:15 +04:00
}
static void _destroy_tags ( struct cmd_context * cmd )
{
2008-11-04 01:14:30 +03:00
struct dm_list * slh , * slht ;
2004-05-04 22:28:15 +04:00
2008-11-04 01:14:30 +03:00
dm_list_iterate_safe ( slh , slht , & cmd - > tags ) {
dm_list_del ( slh ) ;
2004-05-04 22:28:15 +04:00
}
}
int config_files_changed ( struct cmd_context * cmd )
{
struct config_tree_list * cfl ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( cfl , & cmd - > config_files ) {
2011-12-19 01:56:03 +04:00
if ( config_file_changed ( cfl - > cft ) )
2004-05-04 22:28:15 +04:00
return 1 ;
}
return 0 ;
}
2013-06-25 14:25:43 +04:00
static void _destroy_config ( struct cmd_context * cmd )
2004-05-04 22:28:15 +04:00
{
struct config_tree_list * cfl ;
2013-06-25 14:25:43 +04:00
struct dm_config_tree * cft ;
2014-05-19 15:59:23 +04:00
struct profile * profile , * tmp_profile ;
2004-05-04 22:28:15 +04:00
2013-06-25 14:25:43 +04:00
/*
* Configuration cascade :
2013-06-25 14:27:04 +04:00
* CONFIG_STRING - > CONFIG_PROFILE - > CONFIG_FILE / CONFIG_MERGED_FILES
2013-06-25 14:25:43 +04:00
*/
2009-06-15 15:56:31 +04:00
2013-06-25 14:25:43 +04:00
/* 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 ) ;
2004-05-04 22:28:15 +04:00
2013-06-25 14:25:43 +04:00
dm_list_iterate_items ( cfl , & cmd - > config_files )
config_destroy ( cfl - > cft ) ;
2008-11-04 01:14:30 +03:00
dm_list_init ( & cmd - > config_files ) ;
2011-09-02 05:32:08 +04:00
2013-06-25 14:27:04 +04:00
/* CONFIG_PROFILE */
if ( cmd - > profile_params ) {
config: differentiate command and metadata profiles and consolidate profile handling code
- When defining configuration source, the code now uses separate
CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers
(before, it was just CONFIG_PROFILE that did not make the
difference between the two). This helps when checking the
configuration if it contains correct set of options which
are all in either command-profilable or metadata-profilable
group without mixing these groups together - so it's a firm
distinction. The "command profile" can't contain
"metadata profile" and vice versa! This is strictly checked
and if the settings are mixed, such profile is rejected and
it's not used. So in the end, the CONFIG_PROFILE_COMMAND
set of options and CONFIG_PROFILE_METADATA are mutually exclusive
sets.
- Marking configuration with one or the other marker will also
determine the way these configuration sources are positioned
in the configuration cascade which is now:
CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES
- Marking configuration with one or the other marker will also make
it possible to issue a command context refresh (will be probably
a part of a future patch) if needed for settings in global profile
set. For settings in metadata profile set this is impossible since
we can't refresh cmd context in the middle of reading VG/LV metadata
and for each VG/LV separately because each VG/LV can have a different
metadata profile assinged and it's not possible to change these
settings at this level.
- When command profile is incorrect, it's rejected *and also* the
command exits immediately - the profile *must* be correct for the
command that was run with a profile to be executed. Before this
patch, when the profile was found incorrect, there was just the
warning message and the command continued without profile applied.
But it's more correct to exit immediately in this case.
- When metadata profile is incorrect, we reject it during command
runtime (as we know the profile name from metadata and not early
from command line as it is in case of command profiles) and we
*do continue* with the command as we're in the middle of operation.
Also, the metadata profile is applied directly and on the fly on
find_config_tree_* fn call and even if the metadata profile is
found incorrect, we still need to return the non-profiled value
as found in the other configuration provided or default value.
To exit immediately even in this case, we'd need to refactor
existing find_config_tree_* fns so they can return error. Currently,
these fns return only config values (which end up with default
values in the end if the config is not found).
- To check the profile validity before use to be sure it's correct,
one can use :
lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate
(the --commandprofile/--metadataprofile for dumpconfig will come
as part of the subsequent patch)
- This patch also adds a reference to --commandprofile and
--metadataprofile in the cmd help string (which was missing before
for the --profile for some commands). We do not mention --profile
now as people should use --commandprofile or --metadataprofile
directly. However, the --profile is still supported for backward
compatibility and it's translated as:
--profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange
(as these commands are able to attach profile to metadata)
--profile == --commandprofile for all the other commands
(--metadataprofile is not allowed there as it makes no sense)
- This patch also contains some cleanups to make the code handling
the profiles more readable...
2014-05-20 16:13:10 +04:00
remove_config_tree_by_source ( cmd , CONFIG_PROFILE_COMMAND ) ;
remove_config_tree_by_source ( cmd , CONFIG_PROFILE_METADATA ) ;
2014-05-19 15:59:23 +04:00
/*
* 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 ) {
2016-08-08 11:43:18 +03:00
if ( cmd - > is_interactive & & ( profile = = cmd - > profile_params - > shell_profile ) )
continue ;
2013-06-25 14:27:04 +04:00
config_destroy ( profile - > cft ) ;
2014-05-19 15:59:23 +04:00
profile - > cft = NULL ;
dm_list_move ( & cmd - > profile_params - > profiles_to_load , & profile - > list ) ;
}
2013-06-25 14:27:04 +04:00
}
2013-06-25 14:25:43 +04:00
/* 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 " ) ;
2004-05-04 22:28:15 +04:00
}
2002-11-18 17:01:16 +03:00
static int _init_dev_cache ( struct cmd_context * cmd )
{
2011-08-30 18:55:15 +04:00
const struct dm_config_node * cn ;
const struct dm_config_value * cv ;
2012-05-29 12:09:10 +04:00
size_t len , udev_dir_len = strlen ( DM_UDEV_DEV_DIR ) ;
int len_diff ;
2011-04-22 16:05:32 +04:00
int device_list_from_udev ;
2002-11-18 17:01:16 +03:00
2010-10-13 19:40:38 +04:00
init_dev_disable_after_error_count (
2013-06-25 14:30:34 +04:00
find_config_tree_int ( cmd , devices_disable_after_error_count_CFG , NULL ) ) ;
2010-10-13 19:40:38 +04:00
2007-04-26 20:44:59 +04:00
if ( ! dev_cache_init ( cmd ) )
return_0 ;
2002-11-18 17:01:16 +03:00
2012-11-29 17:03:48 +04:00
/*
* Override existing config and hardcode device_list_from_udev = 0 if :
* - udev is not running
* - udev is disabled using DM_DISABLE_UDEV environment variable
*/
2012-11-29 18:50:52 +04:00
if ( _check_disable_udev ( " obtain device list by scanning device directory " ) )
2012-11-29 17:03:48 +04:00
device_list_from_udev = 0 ;
2012-11-29 18:50:52 +04:00
else
2012-11-29 17:03:48 +04:00
device_list_from_udev = udev_is_running ( ) ?
2013-06-25 14:31:53 +04:00
find_config_tree_bool ( cmd , devices_obtain_device_list_from_udev_CFG , NULL ) : 0 ;
2012-11-29 17:03:48 +04:00
2011-04-22 16:05:32 +04:00
init_obtain_device_list_from_udev ( device_list_from_udev ) ;
2015-07-15 11:52:23 +03:00
if ( ! ( cn = find_config_tree_array ( cmd , devices_scan_CFG , NULL ) ) ) {
log_error ( INTERNAL_ERROR " Unable to find configuration for devices/scan. " ) ;
2016-11-25 15:46:06 +03:00
return 0 ;
2002-11-18 17:01:16 +03:00
}
for ( cv = cn - > v ; cv ; cv = cv - > next ) {
2011-08-30 18:55:15 +04:00
if ( cv - > type ! = DM_CFG_STRING ) {
2002-11-18 17:01:16 +03:00
log_error ( " Invalid string in config file: "
" devices/scan " ) ;
return 0 ;
}
2012-05-29 12:09:10 +04:00
if ( device_list_from_udev ) {
2011-04-22 16:05:32 +04:00
len = strlen ( cv - > v . str ) ;
2012-05-29 12:09:10 +04:00
/*
* 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 ) ) {
2013-04-23 13:58:50 +04:00
log_very_verbose ( " Non standard udev dir %s, resetting "
" devices/obtain_device_list_from_udev. " ,
cv - > v . str ) ;
2011-04-22 16:05:32 +04:00
device_list_from_udev = 0 ;
init_obtain_device_list_from_udev ( 0 ) ;
}
}
2002-11-18 17:01:16 +03:00
if ( ! dev_cache_add_dir ( cv - > v . str ) ) {
log_error ( " Failed to add %s to internal device cache " ,
cv - > v . str ) ;
return 0 ;
}
}
2015-07-08 12:22:24 +03:00
if ( ! ( cn = find_config_tree_array ( cmd , devices_loopfiles_CFG , NULL ) ) )
2005-05-03 21:28:23 +04:00
return 1 ;
for ( cv = cn - > v ; cv ; cv = cv - > next ) {
2011-08-30 18:55:15 +04:00
if ( cv - > type ! = DM_CFG_STRING ) {
2005-05-03 21:28:23 +04:00
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 ;
}
}
2002-11-18 17:01:16 +03:00
return 1 ;
}
2018-05-02 22:10:30 +03:00
# define MAX_FILTERS 10
2004-02-13 17:46:04 +03:00
2014-09-23 14:50:09 +04:00
static struct dev_filter * _init_lvmetad_filter_chain ( struct cmd_context * cmd )
2002-11-18 17:01:16 +03:00
{
2012-03-12 18:35:57 +04:00
int nr_filt = 0 ;
2011-08-30 18:55:15 +04:00
const struct dm_config_node * cn ;
2012-06-21 23:19:28 +04:00
struct dev_filter * filters [ MAX_FILTERS ] = { 0 } ;
2012-02-08 14:46:24 +04:00
struct dev_filter * composite ;
2002-11-18 17:01:16 +03:00
2004-04-16 20:12:04 +04:00
/*
* 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 .
2008-01-30 17:00:02 +03:00
* Listed first because it ' s very efficient at eliminating
2004-04-16 20:12:04 +04:00
* unavailable devices .
*/
2013-06-25 14:31:53 +04:00
if ( find_config_tree_bool ( cmd , devices_sysfs_scan_CFG , NULL ) ) {
2013-06-12 13:38:48 +04:00
if ( ( filters [ nr_filt ] = sysfs_filter_create ( ) ) )
2004-02-13 17:46:04 +03:00
nr_filt + + ;
}
2002-11-18 17:01:16 +03:00
2016-05-25 21:57:33 +03:00
/* 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 + + ;
2015-09-08 16:03:15 +03:00
/* global regex filter. Optional. */
2014-09-11 11:30:03 +04:00
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 ;
}
2012-05-23 17:02:36 +04:00
nr_filt + + ;
2014-09-11 11:30:03 +04:00
}
2002-11-18 17:01:16 +03:00
2015-09-08 16:03:15 +03:00
/* 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 + + ;
}
}
2004-04-16 20:12:04 +04:00
/* device type filter. Required. */
2013-06-12 14:08:56 +04:00
if ( ! ( filters [ nr_filt ] = lvm_type_filter_create ( cmd - > dev_types ) ) ) {
2004-02-13 17:46:04 +03:00
log_error ( " Failed to create lvm type filter " ) ;
2012-03-12 18:35:57 +04:00
goto bad ;
2002-11-18 17:01:16 +03:00
}
2012-05-23 17:02:36 +04:00
nr_filt + + ;
2002-11-18 17:01:16 +03:00
2014-09-23 14:50:09 +04:00
/* 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 + + ;
2013-08-14 02:26:58 +04:00
/* 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 + + ;
2018-05-01 22:32:15 +03:00
/* signature filter. Required. */
if ( ! ( filters [ nr_filt ] = signature_filter_create ( cmd - > dev_types ) ) ) {
log_error ( " Failed to create signature device filter " ) ;
goto bad ;
}
nr_filt + + ;
2004-04-16 20:12:04 +04:00
/* md component filter. Optional, non-critical. */
2013-06-25 14:31:53 +04:00
if ( find_config_tree_bool ( cmd , devices_md_component_detection_CFG , NULL ) ) {
2004-11-19 22:25:07 +03:00
init_md_filtering ( 1 ) ;
2018-05-04 01:12:07 +03:00
if ( ( filters [ nr_filt ] = md_filter_create ( cmd , cmd - > dev_types ) ) )
2004-04-16 20:12:04 +04:00
nr_filt + + ;
}
filters: add firmware RAID filter
Just like MD filtering that detects components of software RAID (md),
add detection for firmware RAID.
We're not adding any native code to detect this - there are lots of
firmware RAIDs out there which is just out of LVM scope. However,
with current changes with which we're able to get device info from
external sources (e.g. external_device_info_source="udev"), we can
do this easily if the external device status source has this kind
of information - which is the case of "udev" source where the results
of blkid scans are stored.
This detection should cover all firmware RAIDs that blkid can detect and
which are identified as:
ID_FS_TYPE = {adaptec,ddf,hpt45x,hpt37x,isw,jmicron,lsi_mega,nvidia,promise_fasttrack,silicon_medley,via}_raid_member
2014-09-09 17:05:57 +04:00
/* 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 + + ;
}
2014-12-15 17:12:42 +03:00
if ( ! ( composite = composite_filter_create ( nr_filt , 1 , filters ) ) )
2012-03-12 18:35:57 +04:00
goto_bad ;
2012-02-08 14:46:24 +04:00
return composite ;
2013-08-14 02:26:58 +04:00
2012-03-12 18:35:57 +04:00
bad :
while ( - - nr_filt > = 0 )
2010-04-30 16:37:04 +04:00
filters [ nr_filt ] - > destroy ( filters [ nr_filt ] ) ;
2012-03-12 18:35:57 +04:00
2010-04-30 16:37:04 +04:00
return NULL ;
2002-11-18 17:01:16 +03:00
}
2014-09-23 14:50:09 +04:00
/*
* The way the filtering is initialized depends on whether lvmetad is uesd or not .
*
2014-10-02 14:00:57 +04:00
* If lvmetad is used , there are three filter chains :
2014-09-23 14:50:09 +04:00
*
2014-10-02 14:00:57 +04:00
* - cmd - > lvmetad_filter - the lvmetad filter chain used when scanning devs for lvmetad update :
2016-06-23 10:37:51 +03:00
* sysfs filter - > internal filter - > global regex filter - > type filter - >
2014-09-23 14:50:09 +04:00
* usable device filter ( FILTER_MODE_PRE_LVMETAD ) - >
* mpath component filter - > partitioned filter - >
filters: add firmware RAID filter
Just like MD filtering that detects components of software RAID (md),
add detection for firmware RAID.
We're not adding any native code to detect this - there are lots of
firmware RAIDs out there which is just out of LVM scope. However,
with current changes with which we're able to get device info from
external sources (e.g. external_device_info_source="udev"), we can
do this easily if the external device status source has this kind
of information - which is the case of "udev" source where the results
of blkid scans are stored.
This detection should cover all firmware RAIDs that blkid can detect and
which are identified as:
ID_FS_TYPE = {adaptec,ddf,hpt45x,hpt37x,isw,jmicron,lsi_mega,nvidia,promise_fasttrack,silicon_medley,via}_raid_member
2014-09-09 17:05:57 +04:00
* md component filter - > fw raid filter
2014-09-23 14:50:09 +04:00
*
2014-10-02 14:00:57 +04:00
* - cmd - > filter - the filter chain used for lvmetad responses :
2015-09-08 16:03:15 +03:00
* persistent filter - > regex_filter - > usable device filter ( FILTER_MODE_POST_LVMETAD )
2014-09-23 14:50:09 +04:00
*
2014-10-02 14:00:57 +04:00
* - cmd - > full_filter - the filter chain used for all the remaining situations :
2015-09-08 16:03:15 +03:00
* cmd - > lvmetad_filter - > cmd - > filter
2014-09-23 14:50:09 +04:00
*
2015-09-08 16:03:15 +03:00
* If lvmetad is not used , there ' s just one filter chain :
2014-09-23 14:50:09 +04:00
*
2014-10-02 14:00:57 +04:00
* - cmd - > filter = = cmd - > full_filter :
2016-06-23 10:37:51 +03:00
* persistent filter - > sysfs filter - > internal filter - > global regex filter - >
2015-09-08 16:03:15 +03:00
* regex_filter - > type filter - > usable device filter ( FILTER_MODE_NO_LVMETAD ) - >
* mpath component filter - > partitioned filter - > md component filter - > fw raid filter
2014-09-23 14:50:09 +04:00
*
*/
2015-07-30 11:34:10 +03:00
int init_filters ( struct cmd_context * cmd , unsigned load_persistent_cache )
2002-11-18 17:01:16 +03:00
{
2014-03-03 15:47:32 +04:00
const char * dev_cache ;
2014-09-23 14:50:09 +04:00
struct dev_filter * filter = NULL , * filter_components [ 2 ] = { 0 } ;
2015-09-08 16:03:15 +03:00
int nr_filt ;
2002-11-18 17:01:16 +03:00
struct stat st ;
2012-08-13 21:44:10 +04:00
const struct dm_config_node * cn ;
2015-03-18 12:59:41 +03:00
struct timespec ts , cts ;
2002-11-18 17:01:16 +03:00
2015-07-30 11:34:10 +03:00
if ( ! cmd - > initialized . connections ) {
log_error ( INTERNAL_ERROR " connections must be initialized before filters " ) ;
return 0 ;
}
2002-11-18 17:01:16 +03:00
cmd - > dump_filter = 0 ;
2014-09-23 14:50:09 +04:00
cmd - > lvmetad_filter = _init_lvmetad_filter_chain ( cmd ) ;
if ( ! cmd - > lvmetad_filter )
2012-08-13 21:44:10 +04:00
goto_bad ;
2002-11-18 17:01:16 +03:00
2013-06-25 14:31:53 +04:00
init_ignore_suspended_devices ( find_config_tree_bool ( cmd , devices_ignore_suspended_devices_CFG , NULL ) ) ;
Mirror: Fix hangs and lock-ups caused by attempting label reads of mirrors
There is a problem with the way mirrors have been designed to handle
failures that is resulting in stuck LVM processes and hung I/O. When
mirrors encounter a write failure, they block I/O and notify userspace
to reconfigure the mirror to remove failed devices. This process is
open to a couple races:
1) Any LVM process other than the one that is meant to deal with the
mirror failure can attempt to read the mirror, fail, and block other
LVM commands (including the repair command) from proceeding due to
holding a lock on the volume group.
2) If there are multiple mirrors that suffer a failure in the same
volume group, a repair can block while attempting to read the LVM
label from one mirror while trying to repair the other.
Mitigation of these races has been attempted by disallowing label reading
of mirrors that are either suspended or are indicated as blocking by
the kernel. While this has closed the window of opportunity for hitting
the above problems considerably, it hasn't closed it completely. This is
because it is still possible to start an LVM command, read the status of
the mirror as healthy, and then perform the read for the label at the
moment after a the failure is discovered by the kernel.
I can see two solutions to this problem:
1) Allow users to configure whether mirrors can be candidates for LVM
labels (i.e. whether PVs can be created on mirror LVs). If the user
chooses to allow label scanning of mirror LVs, it will be at the expense
of a possible hang in I/O or LVM processes.
2) Instrument a way to allow asynchronous label reading - allowing
blocked label reads to be ignored while continuing to process the LVM
command. This would action would allow LVM commands to continue even
though they would have otherwise blocked trying to read a mirror. They
can then release their lock and allow a repair command to commence. In
the event of #2 above, the repair command already in progress can continue
and repair the failed mirror.
This patch brings solution #1. If solution #2 is developed later on, the
configuration option created in #1 can be negated - allowing mirrors to
be scanned for labels by default once again.
2013-10-23 04:14:33 +04:00
init_ignore_lvm_mirrors ( find_config_tree_bool ( cmd , devices_ignore_lvm_mirrors_CFG , NULL ) ) ;
2007-01-26 00:22:30 +03:00
2014-09-23 14:50:09 +04:00
/*
* 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 ( ) ) {
2015-09-08 16:03:15 +03:00
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 ) ) ) {
2014-09-23 14:50:09 +04:00
log_verbose ( " Failed to create usable device filter. " ) ;
goto bad ;
}
2015-09-08 16:03:15 +03:00
nr_filt + + ;
if ( ! ( filter = composite_filter_create ( nr_filt , 0 , filter_components ) ) )
goto_bad ;
2014-09-30 18:08:05 +04:00
} else {
2015-09-08 16:03:15 +03:00
filter = cmd - > lvmetad_filter ;
2014-09-30 18:08:05 +04:00
cmd - > lvmetad_filter = NULL ;
}
2014-09-23 14:50:09 +04:00
2014-03-03 15:47:32 +04:00
if ( ! ( dev_cache = find_config_tree_str ( cmd , devices_cache_CFG , NULL ) ) )
goto_bad ;
2007-07-23 14:45:49 +04:00
2014-09-23 14:50:09 +04:00
if ( ! ( filter = persistent_filter_create ( cmd - > dev_types , filter , dev_cache ) ) ) {
2011-01-06 18:29:24 +03:00
log_verbose ( " Failed to create persistent device filter. " ) ;
2013-07-26 14:47:28 +04:00
goto bad ;
2002-11-18 17:01:16 +03:00
}
2014-09-23 14:50:09 +04:00
cmd - > filter = filter ;
2014-10-02 14:00:57 +04:00
if ( lvmetad_used ( ) ) {
2015-09-08 16:03:15 +03:00
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 ) ) )
2014-10-02 14:00:57 +04:00
goto_bad ;
} else
cmd - > full_filter = filter ;
2002-11-18 17:01:16 +03:00
/* Should we ever dump persistent filter state? */
2013-06-25 14:31:53 +04:00
if ( find_config_tree_bool ( cmd , devices_write_cache_state_CFG , NULL ) )
2002-11-18 17:01:16 +03:00
cmd - > dump_filter = 1 ;
2009-02-23 00:14:37 +03:00
if ( ! * cmd - > system_dir )
2002-11-18 17:01:16 +03:00
cmd - > dump_filter = 0 ;
2007-01-23 18:58:06 +03:00
/*
* Only load persistent filter device cache on startup if it is newer
2013-05-27 03:55:14 +04:00
* than the config file and this is not a long - lived process . Also avoid
* it when lvmetad is enabled .
2007-01-23 18:58:06 +03:00
*/
2013-06-25 14:31:53 +04:00
if ( ! find_config_tree_bool ( cmd , global_use_lvmetad_CFG , NULL ) & &
2013-05-27 03:55:14 +04:00
load_persistent_cache & & ! cmd - > is_long_lived & &
2015-03-18 12:59:41 +03:00
! stat ( dev_cache , & st ) ) {
lvm_stat_ctim ( & ts , & st ) ;
cts = config_file_timestamp ( cmd - > cft ) ;
if ( timespeccmp ( & ts , & cts , > ) & &
2018-04-20 18:43:50 +03:00
! persistent_filter_load ( cmd - > filter , NULL ) )
2015-03-18 12:59:41 +03:00
log_verbose ( " Failed to load existing device cache from %s " ,
dev_cache ) ;
}
2002-11-18 17:01:16 +03:00
2015-07-30 11:34:10 +03:00
cmd - > initialized . filters = 1 ;
2002-11-18 17:01:16 +03:00
return 1 ;
2012-08-13 21:44:10 +04:00
bad :
2014-09-23 14:50:09 +04:00
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 ) ;
2014-09-09 19:16:40 +04:00
}
2014-09-23 14:50:09 +04:00
/* if lvmetad is used, the cmd->lvmetad_filter is separate */
2014-09-30 18:08:05 +04:00
if ( cmd - > lvmetad_filter )
2014-09-23 14:50:09 +04:00
cmd - > lvmetad_filter - > destroy ( cmd - > lvmetad_filter ) ;
2015-07-30 11:34:10 +03:00
cmd - > initialized . filters = 0 ;
2012-08-13 21:44:10 +04:00
return 0 ;
2002-11-18 17:01:16 +03:00
}
2010-04-29 05:38:12 +04:00
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 ;
}
2002-11-18 17:01:16 +03:00
static int _init_formats ( struct cmd_context * cmd )
{
const char * format ;
struct format_type * fmt ;
2003-03-24 21:08:53 +03:00
# ifdef HAVE_LIBDL
2011-08-30 18:55:15 +04:00
const struct dm_config_node * cn ;
2003-03-24 21:08:53 +03:00
# endif
2002-11-18 17:01:16 +03:00
2003-03-24 21:08:53 +03:00
# ifdef HAVE_LIBDL
2006-09-01 02:21:00 +04:00
/* Load any formats in shared libs if not static */
2008-12-18 08:27:17 +03:00
if ( ! is_static ( ) & &
2015-07-08 12:22:24 +03:00
( cn = find_config_tree_array ( cmd , global_format_libraries_CFG , NULL ) ) ) {
2003-03-24 21:08:53 +03:00
2011-08-30 18:55:15 +04:00
const struct dm_config_value * cv ;
2003-03-24 21:08:53 +03:00
struct format_type * ( * init_format_fn ) ( struct cmd_context * ) ;
void * lib ;
2002-11-18 17:01:16 +03:00
for ( cv = cn - > v ; cv ; cv = cv - > next ) {
2011-08-30 18:55:15 +04:00
if ( cv - > type ! = DM_CFG_STRING ) {
2002-11-18 17:01:16 +03:00
log_error ( " Invalid string in config file: "
" global/format_libraries " ) ;
return 0 ;
}
2006-05-16 20:48:31 +04:00
if ( ! ( lib = load_shared_library ( cmd , cv - > v . str ,
2008-01-30 16:19:47 +03:00
" format " , 0 ) ) )
return_0 ;
2002-11-18 17:01:16 +03:00
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 ;
}
2010-11-24 12:34:34 +03:00
if ( ! ( fmt = init_format_fn ( cmd ) ) ) {
dlclose ( lib ) ;
return_0 ;
}
2002-11-18 17:01:16 +03:00
fmt - > library = lib ;
2008-11-04 01:14:30 +03:00
dm_list_add ( & cmd - > formats , & fmt - > list ) ;
2002-11-18 17:01:16 +03:00
}
}
2003-03-24 21:08:53 +03:00
# endif
2002-11-18 17:01:16 +03:00
if ( ! ( fmt = create_text_format ( cmd ) ) )
return 0 ;
fmt - > library = NULL ;
2008-11-04 01:14:30 +03:00
dm_list_add ( & cmd - > formats , & fmt - > list ) ;
2002-11-18 17:01:16 +03:00
cmd - > fmt_backup = fmt ;
2013-06-25 14:29:54 +04:00
format = find_config_tree_str ( cmd , global_format_CFG , NULL ) ;
2002-11-18 17:01:16 +03:00
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( fmt , & cmd - > formats ) {
2002-11-18 17:01:16 +03:00
if ( ! strcasecmp ( fmt - > name , format ) | |
( fmt - > alias & & ! strcasecmp ( fmt - > alias , format ) ) ) {
2010-04-29 05:38:12 +04:00
cmd - > default_settings . fmt_name = fmt - > name ;
cmd - > fmt = fmt ;
2002-11-18 17:01:16 +03:00
return 1 ;
}
}
log_error ( " _init_formats: Default format (%s) not found " , format ) ;
return 0 ;
}
2008-04-08 16:49:21 +04:00
int init_lvmcache_orphans ( struct cmd_context * cmd )
{
struct format_type * fmt ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( fmt , & cmd - > formats )
2008-04-08 16:49:21 +04:00
if ( ! lvmcache_add_orphan_vginfo ( fmt - > orphan_vg_name , fmt ) )
return_0 ;
return 1 ;
}
2009-07-08 16:36:01 +04:00
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 ;
}
2009-07-22 00:00:02 +04:00
static int _init_single_segtype ( struct cmd_context * cmd ,
struct segtype_library * seglib )
2009-07-08 16:36:01 +04:00
{
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 ) ;
}
2004-05-05 01:25:57 +04:00
static int _init_segtypes ( struct cmd_context * cmd )
{
2011-08-03 02:07:20 +04:00
int i ;
2004-05-05 01:25:57 +04:00
struct segment_type * segtype ;
2011-08-24 17:41:46 +04:00
struct segtype_library seglib = { . cmd = cmd , . lib = NULL } ;
2011-08-03 02:07:20 +04:00
struct segment_type * ( * init_segtype_array [ ] ) ( struct cmd_context * cmd ) = {
init_striped_segtype ,
init_zero_segtype ,
init_error_segtype ,
2014-10-11 11:10:07 +04:00
/* disabled until needed init_free_segtype, */
2011-08-24 17:41:46 +04:00
# ifdef SNAPSHOT_INTERNAL
init_snapshot_segtype ,
# endif
# ifdef MIRRORED_INTERNAL
init_mirrored_segtype ,
2011-08-03 02:07:20 +04:00
# endif
NULL
} ;
2004-05-05 01:25:57 +04:00
# ifdef HAVE_LIBDL
2011-08-30 18:55:15 +04:00
const struct dm_config_node * cn ;
2004-05-05 01:25:57 +04:00
# endif
2011-08-03 02:07:20 +04:00
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 ) ;
}
2008-06-25 20:52:27 +04:00
2011-08-24 17:41:46 +04:00
# ifdef RAID_INTERNAL
if ( ! init_raid_segtypes ( cmd , & seglib ) )
2010-05-21 16:36:30 +04:00
return 0 ;
# endif
2011-08-25 14:00:09 +04:00
# ifdef THIN_INTERNAL
if ( ! init_thin_segtypes ( cmd , & seglib ) )
return 0 ;
# endif
2014-01-27 15:27:16 +04:00
# ifdef CACHE_INTERNAL
if ( ! init_cache_segtypes ( cmd , & seglib ) )
return 0 ;
# endif
2004-05-05 01:25:57 +04:00
# ifdef HAVE_LIBDL
2006-09-01 02:21:00 +04:00
/* Load any formats in shared libs unless static */
2008-12-18 08:27:17 +03:00
if ( ! is_static ( ) & &
2015-07-08 12:22:24 +03:00
( cn = find_config_tree_array ( cmd , global_segment_libraries_CFG , NULL ) ) ) {
2004-05-05 01:25:57 +04:00
2011-08-30 18:55:15 +04:00
const struct dm_config_value * cv ;
2009-07-22 00:00:02 +04:00
int ( * init_multiple_segtypes_fn ) ( struct cmd_context * ,
struct segtype_library * ) ;
2004-05-05 01:25:57 +04:00
for ( cv = cn - > v ; cv ; cv = cv - > next ) {
2011-08-30 18:55:15 +04:00
if ( cv - > type ! = DM_CFG_STRING ) {
2004-05-05 01:25:57 +04:00
log_error ( " Invalid string in config file: "
" global/segment_libraries " ) ;
return 0 ;
}
2009-07-08 16:36:01 +04:00
seglib . libname = cv - > v . str ;
if ( ! ( seglib . lib = load_shared_library ( cmd ,
seglib . libname ,
2008-01-30 16:19:47 +03:00
" segment type " , 0 ) ) )
return_0 ;
2004-05-05 01:25:57 +04:00
2009-07-08 16:36:01 +04:00
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 ;
2009-07-22 00:00:02 +04:00
if ( ! init_multiple_segtypes_fn ( cmd , & seglib ) ) {
2009-07-08 16:36:01 +04:00
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 ;
2004-05-05 01:25:57 +04:00
}
}
}
# endif
return 1 ;
}
2004-03-08 20:25:59 +03:00
static int _init_hostname ( struct cmd_context * cmd )
{
struct utsname uts ;
if ( uname ( & uts ) ) {
log_sys_error ( " uname " , " _init_hostname " ) ;
return 0 ;
}
2005-10-17 03:03:59 +04:00
if ( ! ( cmd - > hostname = dm_pool_strdup ( cmd - > libmem , uts . nodename ) ) ) {
log_error ( " _init_hostname: dm_pool_strdup failed " ) ;
2004-03-08 20:25:59 +03:00
return 0 ;
}
2005-10-17 03:03:59 +04:00
if ( ! ( cmd - > kernel_vsn = dm_pool_strdup ( cmd - > libmem , uts . release ) ) ) {
log_error ( " _init_hostname: dm_pool_strdup kernel_vsn failed " ) ;
2004-04-08 21:21:01 +04:00
return 0 ;
}
2004-03-08 20:25:59 +03:00
return 1 ;
}
2005-05-17 17:46:38 +04:00
static int _init_backup ( struct cmd_context * cmd )
{
uint32_t days , min ;
const char * dir ;
2010-11-29 13:58:32 +03:00
if ( ! cmd - > system_dir [ 0 ] ) {
2005-05-17 17:46:38 +04:00
log_warn ( " WARNING: Metadata changes will NOT be backed up " ) ;
2008-12-11 06:33:35 +03:00
backup_init ( cmd , " " , 0 ) ;
2008-12-11 06:32:56 +03:00
archive_init ( cmd , " " , 0 , 0 , 0 ) ;
2005-05-17 17:46:38 +04:00
return 1 ;
}
/* set up archiving */
cmd - > default_settings . archive =
2013-06-25 14:31:53 +04:00
find_config_tree_bool ( cmd , backup_archive_CFG , NULL ) ;
2005-05-17 17:46:38 +04:00
2013-06-25 14:30:34 +04:00
days = ( uint32_t ) find_config_tree_int ( cmd , backup_retain_days_CFG , NULL ) ;
2005-05-17 17:46:38 +04:00
2013-06-25 14:30:34 +04:00
min = ( uint32_t ) find_config_tree_int ( cmd , backup_retain_min_CFG , NULL ) ;
2005-05-17 17:46:38 +04:00
2013-06-25 14:29:54 +04:00
if ( ! ( dir = find_config_tree_str ( cmd , backup_archive_dir_CFG , NULL ) ) )
2014-03-03 16:24:30 +04:00
return_0 ;
2005-05-17 17:46:38 +04:00
2008-12-11 06:32:56 +03:00
if ( ! archive_init ( cmd , dir , days , min ,
cmd - > default_settings . archive ) ) {
2009-04-03 00:46:11 +04:00
log_debug ( " archive_init failed. " ) ;
2005-05-17 17:46:38 +04:00
return 0 ;
}
/* set up the backup */
2013-06-25 14:31:53 +04:00
cmd - > default_settings . backup = find_config_tree_bool ( cmd , backup_backup_CFG , NULL ) ;
2005-05-17 17:46:38 +04:00
2013-06-25 14:29:54 +04:00
if ( ! ( dir = find_config_tree_str ( cmd , backup_backup_dir_CFG , NULL ) ) )
2014-03-03 16:24:30 +04:00
return_0 ;
2005-05-17 17:46:38 +04:00
2008-12-11 06:33:35 +03:00
if ( ! backup_init ( cmd , dir , cmd - > default_settings . backup ) ) {
2005-05-17 17:46:38 +04:00
log_debug ( " backup_init failed. " ) ;
return 0 ;
}
return 1 ;
}
2008-12-07 07:27:56 +03:00
static void _init_rand ( struct cmd_context * cmd )
{
2010-06-02 01:47:57 +04:00
if ( read_urandom ( & cmd - > rand_seed , sizeof ( cmd - > rand_seed ) ) ) {
reset_lvm_errno ( 1 ) ;
2008-12-07 07:27:56 +03:00
return ;
2010-06-02 01:47:57 +04:00
}
2008-12-07 07:27:56 +03:00
cmd - > rand_seed = ( unsigned ) time ( NULL ) + ( unsigned ) getpid ( ) ;
2010-06-02 01:47:57 +04:00
reset_lvm_errno ( 1 ) ;
2008-12-07 07:27:56 +03:00
}
2008-12-12 06:30:41 +03:00
static void _init_globals ( struct cmd_context * cmd )
{
init_mirror_in_sync ( 0 ) ;
}
2016-04-14 01:00:01 +03:00
/*
* 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 .
*
*/
2015-07-30 11:13:45 +03:00
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 ) ) {
2016-04-14 01:00:01 +03:00
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 ) ) {
2016-04-21 18:28:01 +03:00
if ( lvmetad_pidfile_present ( ) ) {
2016-04-14 01:00:01 +03:00
log_warn ( " WARNING: Not using lvmetad because config setting use_lvmetad=0. " ) ;
2016-04-21 18:28:01 +03:00
log_warn ( " WARNING: To avoid corruption, rescan devices to make changes visible (pvscan --cache). " ) ;
}
2016-04-14 01:00:01 +03:00
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 ;
}
2015-07-30 11:13:45 +03:00
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 ;
}
2015-07-30 11:34:10 +03:00
int init_connections ( struct cmd_context * cmd )
2015-07-30 11:13:45 +03:00
{
2015-07-30 11:34:10 +03:00
2015-07-30 11:13:45 +03:00
if ( ! _init_lvmetad ( cmd ) ) {
log_error ( " Failed to initialize lvmetad connection. " ) ;
2015-07-30 11:34:10 +03:00
goto bad ;
2015-07-30 11:13:45 +03:00
}
if ( ! _init_lvmpolld ( cmd ) ) {
log_error ( " Failed to initialize lvmpolld connection. " ) ;
2015-07-30 11:34:10 +03:00
goto bad ;
2015-07-30 11:13:45 +03:00
}
2015-07-30 11:34:10 +03:00
cmd - > initialized . connections = 1 ;
2015-07-30 11:13:45 +03:00
return 1 ;
2015-07-30 11:34:10 +03:00
bad :
cmd - > initialized . connections = 0 ;
return 0 ;
2015-07-30 11:13:45 +03:00
}
2017-01-23 16:21:56 +03:00
int init_run_by_dmeventd ( struct cmd_context * cmd )
{
init_dmeventd_monitor ( DMEVENTD_MONITOR_IGNORE ) ;
init_ignore_suspended_devices ( 1 ) ;
init_disable_dmeventd_monitoring ( 1 ) ; /* Lock settings */
return 0 ;
}
2016-05-17 19:54:13 +03:00
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 .
toolcontext: light context missed to set-up mem mempool
If cmd->mem was null, then systemd generator was failing on:
(gdb) bt
dm_pool_alloc_aligned (p=0x0, s=96, alignment=8) at mm/pool-fast.c:95
dm_pool_alloc (p=0x0, s=96) at mm/pool-fast.c:90
dm_pool_zalloc (p=0x0, s=96) at mm/pool.c:74
config_file_read_fd (mem=0x0, cft=0x55f4339dbad0, dev=0x55f4339dfac0, reason=DEV_IO_MDA_CONTENT, offset=0, size=82293, offset2=0, size2=0,
checksum_fn=0x0, checksum=0, checksum_only=0, no_dup_node_check=0, ioflags=0, config_file_read_fd_callback=0x0, config_file_read_fd_context=0x0) at config/config.c:567
config_file_read (mem=0x0, cft=0x55f4339dbad0) at config/config.c:658
config_file_open_and_read (config_file=0x7f49aef14540 <config_file> "/var/tmp/lvm/etc/lvm/lvm.conf", source=CONFIG_FILE, cmd=0x55f4339d6260)
at config/config.c:282
_load_config_file (cmd=0x55f4339d6260, tag=0x7f49aeca15da "", local=0) at commands/toolcontext.c:824
_init_lvm_conf (cmd=0x55f4339d6260) at commands/toolcontext.c:853
create_config_context () at commands/toolcontext.c:1814
lvm_config_find_bool (libh=0x0, config_path=0x55f431a884ad "global/use_lvmetad", fail=0) at lvm_base.c:144
main ()
2018-02-09 17:39:14 +03:00
*
* FIXME : this needs to go back to parametrized create_toolcontext ( )
2016-05-17 19:54:13 +03:00
*/
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 ;
toolcontext: light context missed to set-up mem mempool
If cmd->mem was null, then systemd generator was failing on:
(gdb) bt
dm_pool_alloc_aligned (p=0x0, s=96, alignment=8) at mm/pool-fast.c:95
dm_pool_alloc (p=0x0, s=96) at mm/pool-fast.c:90
dm_pool_zalloc (p=0x0, s=96) at mm/pool.c:74
config_file_read_fd (mem=0x0, cft=0x55f4339dbad0, dev=0x55f4339dfac0, reason=DEV_IO_MDA_CONTENT, offset=0, size=82293, offset2=0, size2=0,
checksum_fn=0x0, checksum=0, checksum_only=0, no_dup_node_check=0, ioflags=0, config_file_read_fd_callback=0x0, config_file_read_fd_context=0x0) at config/config.c:567
config_file_read (mem=0x0, cft=0x55f4339dbad0) at config/config.c:658
config_file_open_and_read (config_file=0x7f49aef14540 <config_file> "/var/tmp/lvm/etc/lvm/lvm.conf", source=CONFIG_FILE, cmd=0x55f4339d6260)
at config/config.c:282
_load_config_file (cmd=0x55f4339d6260, tag=0x7f49aeca15da "", local=0) at commands/toolcontext.c:824
_init_lvm_conf (cmd=0x55f4339d6260) at commands/toolcontext.c:853
create_config_context () at commands/toolcontext.c:1814
lvm_config_find_bool (libh=0x0, config_path=0x55f431a884ad "global/use_lvmetad", fail=0) at lvm_base.c:144
main ()
2018-02-09 17:39:14 +03:00
if ( ! ( cmd - > mem = dm_pool_create ( " command " , 4 * 1024 ) ) )
goto out ;
2016-05-17 19:54:13 +03:00
dm_list_init ( & cmd - > config_files ) ;
2016-09-23 15:51:15 +03:00
dm_list_init ( & cmd - > tags ) ;
2016-05-17 19:54:13 +03:00
if ( ! _init_lvm_conf ( cmd ) )
goto_out ;
2016-09-23 15:51:15 +03:00
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 ;
2016-05-17 19:54:13 +03:00
return cmd ;
out :
if ( cmd )
destroy_config_context ( cmd ) ;
return NULL ;
}
2002-11-18 17:01:16 +03:00
/* Entry point */
2018-05-03 00:58:49 +03:00
struct cmd_context * create_toolcontext ( unsigned is_clvmd ,
2011-05-07 17:50:11 +04:00
const char * system_dir ,
2011-12-09 01:24:08 +04:00
unsigned set_buffering ,
2015-07-30 11:34:10 +03:00
unsigned threaded ,
unsigned set_connections ,
unsigned set_filters )
2002-11-18 17:01:16 +03:00
{
struct cmd_context * cmd ;
2013-08-29 02:55:14 +04:00
int flags ;
2002-11-18 17:01:16 +03:00
2003-07-05 02:34:56 +04:00
# ifdef M_MMAP_MAX
mallopt ( M_MMAP_MAX , 0 ) ;
# endif
2002-11-18 17:01:16 +03:00
if ( ! setlocale ( LC_ALL , " " ) )
2004-06-29 17:28:57 +04:00
log_very_verbose ( " setlocale failed " ) ;
2002-11-18 17:01:16 +03:00
2004-02-14 01:56:45 +03:00
# ifdef INTL_PACKAGE
bindtextdomain ( INTL_PACKAGE , LOCALEDIR ) ;
# endif
2002-11-18 17:01:16 +03:00
init_syslog ( DEFAULT_LOG_FACILITY ) ;
2010-10-01 01:06:50 +04:00
if ( ! ( cmd = dm_zalloc ( sizeof ( * cmd ) ) ) ) {
2002-11-18 17:01:16 +03:00
log_error ( " Failed to allocate command context " ) ;
return NULL ;
}
2018-05-03 00:58:49 +03:00
cmd - > is_long_lived = is_clvmd ;
cmd - > is_clvmd = is_clvmd ;
2011-12-09 01:24:08 +04:00
cmd - > threaded = threaded ? 1 : 0 ;
2008-09-19 10:42:00 +04:00
cmd - > handles_missing_pvs = 0 ;
2009-10-16 21:41:49 +04:00
cmd - > handles_unknown_segments = 0 ;
2010-12-11 01:39:52 +03:00
cmd - > independent_metadata_areas = 0 ;
2013-10-02 00:20:10 +04:00
cmd - > ignore_clustered_vgs = 0 ;
2004-05-04 22:28:15 +04:00
cmd - > hosttags = 0 ;
2010-11-11 20:29:05 +03:00
dm_list_init ( & cmd - > arg_value_groups ) ;
2008-11-04 01:14:30 +03:00
dm_list_init ( & cmd - > formats ) ;
dm_list_init ( & cmd - > segtypes ) ;
dm_list_init ( & cmd - > tags ) ;
dm_list_init ( & cmd - > config_files ) ;
2012-02-08 17:44:49 +04:00
label_init ( ) ;
2002-11-18 17:01:16 +03:00
2009-07-16 04:36:59 +04:00
/* FIXME Make this configurable? */
reset_lvm_errno ( 1 ) ;
2012-10-12 18:52:38 +04:00
# ifndef VALGRIND_POOL
2011-05-07 17:50:11 +04:00
/* Set in/out stream buffering before glibc */
2018-02-09 02:26:22 +03:00
if ( set_buffering
# ifdef SYS_gettid
/* For threaded programs no changes of streams */
/* On linux gettid() is implemented only via syscall */
& & ( syscall ( SYS_gettid ) = = getpid ( ) )
# endif
) {
2011-05-07 17:50:11 +04:00
/* Allocate 2 buffers */
2017-10-18 17:57:46 +03:00
if ( ! ( cmd - > linebuffer = dm_malloc ( 2 * _linebuffer_size ) ) ) {
2011-05-07 17:50:11 +04:00
log_error ( " Failed to allocate line buffer. " ) ;
goto out ;
}
2012-08-26 03:19:52 +04:00
2013-08-29 02:55:14 +04:00
/* nohup might set stdin O_WRONLY ! */
if ( is_valid_fd ( STDIN_FILENO ) & &
( ( flags = fcntl ( STDIN_FILENO , F_GETFL ) ) > 0 ) & &
( flags & O_ACCMODE ) ! = O_WRONLY ) {
2016-07-08 17:47:51 +03:00
if ( ! reopen_standard_stream ( & stdin , " r " ) )
2012-08-27 15:07:07 +04:00
goto_out ;
2017-10-18 17:57:46 +03:00
if ( setvbuf ( stdin , cmd - > linebuffer , _IOLBF , _linebuffer_size ) ) {
2012-08-27 15:07:07 +04:00
log_sys_error ( " setvbuf " , " " ) ;
goto out ;
}
2012-08-26 03:19:52 +04:00
}
2013-08-29 02:55:14 +04:00
if ( is_valid_fd ( STDOUT_FILENO ) & &
( ( flags = fcntl ( STDOUT_FILENO , F_GETFL ) ) > 0 ) & &
( flags & O_ACCMODE ) ! = O_RDONLY ) {
2016-07-08 17:47:51 +03:00
if ( ! reopen_standard_stream ( & stdout , " w " ) )
2012-08-27 15:07:07 +04:00
goto_out ;
2017-10-18 17:57:46 +03:00
if ( setvbuf ( stdout , cmd - > linebuffer + _linebuffer_size ,
_IOLBF , _linebuffer_size ) ) {
2012-08-27 15:07:07 +04:00
log_sys_error ( " setvbuf " , " " ) ;
goto out ;
}
2011-05-07 17:50:11 +04:00
}
/* Buffers are used for lines without '\n' */
2018-02-09 02:26:22 +03:00
} else if ( ! set_buffering )
2012-08-26 03:15:45 +04:00
/* Without buffering, must not use stdin/stdout */
init_silent ( 1 ) ;
2012-10-12 18:52:38 +04:00
# endif
2009-02-23 00:14:37 +03:00
/*
* 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 ) ;
2002-11-18 17:01:16 +03:00
if ( ! _get_env_vars ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2002-11-18 17:01:16 +03:00
/* Create system directory if it doesn't already exist */
2009-02-23 00:14:37 +03:00
if ( * cmd - > system_dir & & ! dm_create_dir ( cmd - > system_dir ) ) {
2005-01-27 18:50:34 +03:00
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. " ) ;
2009-07-16 04:36:59 +04:00
goto out ;
2005-01-27 18:50:34 +03:00
}
2002-11-18 17:01:16 +03:00
2005-10-17 03:03:59 +04:00
if ( ! ( cmd - > libmem = dm_pool_create ( " library " , 4 * 1024 ) ) ) {
2004-03-08 20:25:59 +03:00
log_error ( " Library memory pool creation failed " ) ;
2009-07-16 04:36:59 +04:00
goto out ;
2004-03-08 20:25:59 +03:00
}
2014-03-03 15:29:25 +04:00
if ( ! ( cmd - > mem = dm_pool_create ( " command " , 4 * 1024 ) ) ) {
log_error ( " Command memory pool creation failed " ) ;
goto out ;
}
2004-05-04 22:28:15 +04:00
if ( ! _init_lvm_conf ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2004-05-04 22:28:15 +04:00
_init_logging ( cmd ) ;
if ( ! _init_hostname ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2004-05-04 22:28:15 +04:00
if ( ! _init_tags ( cmd , cmd - > cft ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2004-05-04 22:28:15 +04:00
2015-02-23 23:11:00 +03:00
/* Load lvmlocal.conf */
if ( * cmd - > system_dir & & ! _load_config_file ( cmd , " " , 1 ) )
2015-02-25 19:36:47 +03:00
goto_out ;
2015-02-23 23:11:00 +03:00
2004-05-04 22:28:15 +04:00
if ( ! _init_tag_configs ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2004-05-04 22:28:15 +04:00
2011-09-02 05:32:08 +04:00
if ( ! ( cmd - > cft = _merge_config_files ( cmd , cmd - > cft ) ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2004-05-04 22:28:15 +04:00
2002-11-18 17:01:16 +03:00
if ( ! _process_config ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2002-11-18 17:01:16 +03:00
2013-06-25 14:27:04 +04:00
if ( ! _init_profiles ( cmd ) )
goto_out ;
2013-06-12 14:08:56 +04:00
if ( ! ( cmd - > dev_types = create_dev_types ( cmd - > proc_dir ,
2015-07-08 12:22:24 +03:00
find_config_tree_array ( cmd , devices_types_CFG , NULL ) ) ) )
2013-06-12 14:08:56 +04:00
goto_out ;
2002-11-18 17:01:16 +03:00
if ( ! _init_dev_cache ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2002-11-18 17:01:16 +03:00
2003-07-05 02:34:56 +04:00
memlock_init ( cmd ) ;
2002-11-18 17:01:16 +03:00
if ( ! _init_formats ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2002-11-18 17:01:16 +03:00
2018-05-03 00:58:49 +03:00
if ( ! lvmcache_init ( cmd ) )
goto_out ;
/* FIXME: move into lvmcache_init */
2008-04-08 16:49:21 +04:00
if ( ! init_lvmcache_orphans ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2008-04-08 16:49:21 +04:00
2016-06-06 23:20:55 +03:00
dm_list_init ( & cmd - > unused_duplicate_devs ) ;
2004-05-05 01:25:57 +04:00
if ( ! _init_segtypes ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2004-05-05 01:25:57 +04:00
2005-05-17 17:46:38 +04:00
if ( ! _init_backup ( cmd ) )
2009-07-16 04:36:59 +04:00
goto_out ;
2005-05-17 17:46:38 +04:00
2008-12-07 07:27:56 +03:00
_init_rand ( cmd ) ;
2008-12-12 06:30:41 +03:00
_init_globals ( cmd ) ;
2015-07-30 11:34:10 +03:00
if ( set_connections & & ! init_connections ( cmd ) )
2016-05-12 21:00:33 +03:00
goto_out ;
2015-07-30 11:34:10 +03:00
if ( set_filters & & ! init_filters ( cmd , 1 ) )
goto_out ;
2002-11-18 17:01:16 +03:00
cmd - > current_settings = cmd - > default_settings ;
2015-07-30 10:59:39 +03:00
cmd - > initialized . config = 1 ;
2009-07-16 04:36:59 +04:00
out :
2015-07-30 10:59:39 +03:00
if ( ! cmd - > initialized . config ) {
2012-03-12 18:15:04 +04:00
destroy_toolcontext ( cmd ) ;
cmd = NULL ;
}
2002-11-18 17:01:16 +03:00
return cmd ;
}
2010-04-29 05:38:12 +04:00
static void _destroy_formats ( struct cmd_context * cmd , struct dm_list * formats )
2002-11-18 17:01:16 +03:00
{
2008-11-04 01:14:30 +03:00
struct dm_list * fmtl , * tmp ;
2002-11-18 17:01:16 +03:00
struct format_type * fmt ;
void * lib ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_safe ( fmtl , tmp , formats ) {
fmt = dm_list_item ( fmtl , struct format_type ) ;
dm_list_del ( & fmt - > list ) ;
2002-11-18 17:01:16 +03:00
lib = fmt - > library ;
fmt - > ops - > destroy ( fmt ) ;
2003-03-24 21:08:53 +03:00
# ifdef HAVE_LIBDL
2002-11-18 17:01:16 +03:00
if ( lib )
dlclose ( lib ) ;
2003-03-24 21:08:53 +03:00
# endif
2002-11-18 17:01:16 +03:00
}
2010-12-11 01:39:52 +03:00
cmd - > independent_metadata_areas = 0 ;
2002-11-18 17:01:16 +03:00
}
2008-11-04 01:14:30 +03:00
static void _destroy_segtypes ( struct dm_list * segtypes )
2004-05-05 01:25:57 +04:00
{
2008-11-04 01:14:30 +03:00
struct dm_list * sgtl , * tmp ;
2004-05-05 01:25:57 +04:00
struct segment_type * segtype ;
void * lib ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_safe ( sgtl , tmp , segtypes ) {
segtype = dm_list_item ( sgtl , struct segment_type ) ;
dm_list_del ( & segtype - > list ) ;
2004-05-05 01:25:57 +04:00
lib = segtype - > library ;
segtype - > ops - > destroy ( segtype ) ;
# ifdef HAVE_LIBDL
2009-07-08 16:36:01 +04:00
/*
* 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 ;
2004-05-05 01:25:57 +04:00
dlclose ( lib ) ;
2009-07-08 16:36:01 +04:00
skip_dlclose :
;
}
2004-05-05 01:25:57 +04:00
# endif
}
}
2013-06-12 14:08:56 +04:00
static void _destroy_dev_types ( struct cmd_context * cmd )
{
if ( ! cmd - > dev_types )
return ;
dm_free ( cmd - > dev_types ) ;
cmd - > dev_types = NULL ;
}
2014-09-23 14:50:09 +04:00
static void _destroy_filters ( struct cmd_context * cmd )
2009-11-24 19:10:25 +03:00
{
2014-10-02 14:00:57 +04:00
if ( cmd - > full_filter ) {
cmd - > full_filter - > destroy ( cmd - > full_filter ) ;
cmd - > lvmetad_filter = cmd - > filter = cmd - > full_filter = NULL ;
2009-11-24 19:10:25 +03:00
}
2015-07-30 11:34:10 +03:00
cmd - > initialized . filters = 0 ;
2014-09-23 14:50:09 +04:00
}
2009-11-24 19:10:25 +03:00
2014-09-23 14:50:09 +04:00
int refresh_filters ( struct cmd_context * cmd )
{
int r , saved_ignore_suspended_devices = ignore_suspended_devices ( ) ;
2012-08-13 21:44:10 +04:00
2015-07-30 11:34:10 +03:00
if ( ! cmd - > initialized . filters )
/* if filters not initialized, there's nothing to refresh */
return 1 ;
2014-09-23 14:50:09 +04:00
_destroy_filters ( cmd ) ;
2015-07-30 11:34:10 +03:00
if ( ! ( r = init_filters ( cmd , 0 ) ) )
2011-10-11 13:09:00 +04:00
stack ;
2010-01-19 16:25:00 +03:00
/*
* During repair code must not reset suspended flag .
*/
init_ignore_suspended_devices ( saved_ignore_suspended_devices ) ;
return r ;
2009-11-24 19:10:25 +03:00
}
2004-05-04 22:28:15 +04:00
int refresh_toolcontext ( struct cmd_context * cmd )
{
2011-09-02 05:32:08 +04:00
struct dm_config_tree * cft_cmdline , * cft_tmp ;
config: differentiate command and metadata profiles and consolidate profile handling code
- When defining configuration source, the code now uses separate
CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers
(before, it was just CONFIG_PROFILE that did not make the
difference between the two). This helps when checking the
configuration if it contains correct set of options which
are all in either command-profilable or metadata-profilable
group without mixing these groups together - so it's a firm
distinction. The "command profile" can't contain
"metadata profile" and vice versa! This is strictly checked
and if the settings are mixed, such profile is rejected and
it's not used. So in the end, the CONFIG_PROFILE_COMMAND
set of options and CONFIG_PROFILE_METADATA are mutually exclusive
sets.
- Marking configuration with one or the other marker will also
determine the way these configuration sources are positioned
in the configuration cascade which is now:
CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES
- Marking configuration with one or the other marker will also make
it possible to issue a command context refresh (will be probably
a part of a future patch) if needed for settings in global profile
set. For settings in metadata profile set this is impossible since
we can't refresh cmd context in the middle of reading VG/LV metadata
and for each VG/LV separately because each VG/LV can have a different
metadata profile assinged and it's not possible to change these
settings at this level.
- When command profile is incorrect, it's rejected *and also* the
command exits immediately - the profile *must* be correct for the
command that was run with a profile to be executed. Before this
patch, when the profile was found incorrect, there was just the
warning message and the command continued without profile applied.
But it's more correct to exit immediately in this case.
- When metadata profile is incorrect, we reject it during command
runtime (as we know the profile name from metadata and not early
from command line as it is in case of command profiles) and we
*do continue* with the command as we're in the middle of operation.
Also, the metadata profile is applied directly and on the fly on
find_config_tree_* fn call and even if the metadata profile is
found incorrect, we still need to return the non-profiled value
as found in the other configuration provided or default value.
To exit immediately even in this case, we'd need to refactor
existing find_config_tree_* fns so they can return error. Currently,
these fns return only config values (which end up with default
values in the end if the config is not found).
- To check the profile validity before use to be sure it's correct,
one can use :
lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate
(the --commandprofile/--metadataprofile for dumpconfig will come
as part of the subsequent patch)
- This patch also adds a reference to --commandprofile and
--metadataprofile in the cmd help string (which was missing before
for the --profile for some commands). We do not mention --profile
now as people should use --commandprofile or --metadataprofile
directly. However, the --profile is still supported for backward
compatibility and it's translated as:
--profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange
(as these commands are able to attach profile to metadata)
--profile == --commandprofile for all the other commands
(--metadataprofile is not allowed there as it makes no sense)
- This patch also contains some cleanups to make the code handling
the profiles more readable...
2014-05-20 16:13:10 +04:00
const char * profile_command_name , * profile_metadata_name ;
2014-05-19 15:59:23 +04:00
struct profile * profile ;
2011-09-02 05:32:08 +04:00
2004-05-04 22:28:15 +04:00
log_verbose ( " Reloading config files " ) ;
2007-01-23 18:58:06 +03:00
/*
* Don ' t update the persistent filter cache as we will
* perform a full rescan .
*/
2004-05-04 22:28:15 +04:00
2006-05-16 20:48:31 +04:00
activation_release ( ) ;
2014-03-22 01:26:39 +04:00
lvmcache_destroy ( cmd , 0 , 0 ) ;
2018-02-07 00:18:11 +03:00
label_scan_destroy ( cmd ) ;
2004-05-04 22:28:15 +04:00
label_exit ( ) ;
2004-05-05 01:25:57 +04:00
_destroy_segtypes ( & cmd - > segtypes ) ;
2010-04-29 05:38:12 +04:00
_destroy_formats ( cmd , & cmd - > formats ) ;
2014-09-23 14:50:09 +04:00
2014-03-25 13:53:42 +04:00
if ( ! dev_cache_exit ( ) )
stack ;
2013-06-12 14:08:56 +04:00
_destroy_dev_types ( cmd ) ;
2004-05-04 22:28:15 +04:00
_destroy_tags ( cmd ) ;
2012-01-23 21:46:31 +04:00
2014-05-19 15:59:23 +04:00
/* save config string passed on the command line */
2013-06-25 14:25:43 +04:00
cft_cmdline = remove_config_tree_by_source ( cmd , CONFIG_STRING ) ;
2014-05-19 15:59:23 +04:00
/* save the global profile name used */
config: differentiate command and metadata profiles and consolidate profile handling code
- When defining configuration source, the code now uses separate
CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers
(before, it was just CONFIG_PROFILE that did not make the
difference between the two). This helps when checking the
configuration if it contains correct set of options which
are all in either command-profilable or metadata-profilable
group without mixing these groups together - so it's a firm
distinction. The "command profile" can't contain
"metadata profile" and vice versa! This is strictly checked
and if the settings are mixed, such profile is rejected and
it's not used. So in the end, the CONFIG_PROFILE_COMMAND
set of options and CONFIG_PROFILE_METADATA are mutually exclusive
sets.
- Marking configuration with one or the other marker will also
determine the way these configuration sources are positioned
in the configuration cascade which is now:
CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES
- Marking configuration with one or the other marker will also make
it possible to issue a command context refresh (will be probably
a part of a future patch) if needed for settings in global profile
set. For settings in metadata profile set this is impossible since
we can't refresh cmd context in the middle of reading VG/LV metadata
and for each VG/LV separately because each VG/LV can have a different
metadata profile assinged and it's not possible to change these
settings at this level.
- When command profile is incorrect, it's rejected *and also* the
command exits immediately - the profile *must* be correct for the
command that was run with a profile to be executed. Before this
patch, when the profile was found incorrect, there was just the
warning message and the command continued without profile applied.
But it's more correct to exit immediately in this case.
- When metadata profile is incorrect, we reject it during command
runtime (as we know the profile name from metadata and not early
from command line as it is in case of command profiles) and we
*do continue* with the command as we're in the middle of operation.
Also, the metadata profile is applied directly and on the fly on
find_config_tree_* fn call and even if the metadata profile is
found incorrect, we still need to return the non-profiled value
as found in the other configuration provided or default value.
To exit immediately even in this case, we'd need to refactor
existing find_config_tree_* fns so they can return error. Currently,
these fns return only config values (which end up with default
values in the end if the config is not found).
- To check the profile validity before use to be sure it's correct,
one can use :
lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate
(the --commandprofile/--metadataprofile for dumpconfig will come
as part of the subsequent patch)
- This patch also adds a reference to --commandprofile and
--metadataprofile in the cmd help string (which was missing before
for the --profile for some commands). We do not mention --profile
now as people should use --commandprofile or --metadataprofile
directly. However, the --profile is still supported for backward
compatibility and it's translated as:
--profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange
(as these commands are able to attach profile to metadata)
--profile == --commandprofile for all the other commands
(--metadataprofile is not allowed there as it makes no sense)
- This patch also contains some cleanups to make the code handling
the profiles more readable...
2014-05-20 16:13:10 +04:00
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 ;
2014-05-19 15:59:23 +04:00
2013-06-25 14:25:43 +04:00
_destroy_config ( cmd ) ;
2004-05-04 22:28:15 +04:00
2015-07-30 10:59:39 +03:00
cmd - > initialized . config = 0 ;
2004-05-04 22:28:15 +04:00
cmd - > hosttags = 0 ;
2013-12-06 19:35:54 +04:00
cmd - > lib_dir = NULL ;
2004-05-04 22:28:15 +04:00
if ( ! _init_lvm_conf ( cmd ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2004-05-04 22:28:15 +04:00
2011-09-02 05:32:08 +04:00
/* 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 ) ;
2014-05-19 15:59:23 +04:00
/* Reload the global profile. */
config: differentiate command and metadata profiles and consolidate profile handling code
- When defining configuration source, the code now uses separate
CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers
(before, it was just CONFIG_PROFILE that did not make the
difference between the two). This helps when checking the
configuration if it contains correct set of options which
are all in either command-profilable or metadata-profilable
group without mixing these groups together - so it's a firm
distinction. The "command profile" can't contain
"metadata profile" and vice versa! This is strictly checked
and if the settings are mixed, such profile is rejected and
it's not used. So in the end, the CONFIG_PROFILE_COMMAND
set of options and CONFIG_PROFILE_METADATA are mutually exclusive
sets.
- Marking configuration with one or the other marker will also
determine the way these configuration sources are positioned
in the configuration cascade which is now:
CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES
- Marking configuration with one or the other marker will also make
it possible to issue a command context refresh (will be probably
a part of a future patch) if needed for settings in global profile
set. For settings in metadata profile set this is impossible since
we can't refresh cmd context in the middle of reading VG/LV metadata
and for each VG/LV separately because each VG/LV can have a different
metadata profile assinged and it's not possible to change these
settings at this level.
- When command profile is incorrect, it's rejected *and also* the
command exits immediately - the profile *must* be correct for the
command that was run with a profile to be executed. Before this
patch, when the profile was found incorrect, there was just the
warning message and the command continued without profile applied.
But it's more correct to exit immediately in this case.
- When metadata profile is incorrect, we reject it during command
runtime (as we know the profile name from metadata and not early
from command line as it is in case of command profiles) and we
*do continue* with the command as we're in the middle of operation.
Also, the metadata profile is applied directly and on the fly on
find_config_tree_* fn call and even if the metadata profile is
found incorrect, we still need to return the non-profiled value
as found in the other configuration provided or default value.
To exit immediately even in this case, we'd need to refactor
existing find_config_tree_* fns so they can return error. Currently,
these fns return only config values (which end up with default
values in the end if the config is not found).
- To check the profile validity before use to be sure it's correct,
one can use :
lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate
(the --commandprofile/--metadataprofile for dumpconfig will come
as part of the subsequent patch)
- This patch also adds a reference to --commandprofile and
--metadataprofile in the cmd help string (which was missing before
for the --profile for some commands). We do not mention --profile
now as people should use --commandprofile or --metadataprofile
directly. However, the --profile is still supported for backward
compatibility and it's translated as:
--profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange
(as these commands are able to attach profile to metadata)
--profile == --commandprofile for all the other commands
(--metadataprofile is not allowed there as it makes no sense)
- This patch also contains some cleanups to make the code handling
the profiles more readable...
2014-05-20 16:13:10 +04:00
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 ) ) | |
2014-05-19 15:59:23 +04:00
! override_config_tree_from_profile ( cmd , profile ) )
return_0 ;
}
2011-09-02 05:32:08 +04:00
/* Uses cmd->cft i.e. cft_cmdline + lvm.conf */
2004-05-04 22:28:15 +04:00
_init_logging ( cmd ) ;
2011-09-02 05:32:08 +04:00
/* Init tags from lvm.conf. */
if ( ! _init_tags ( cmd , cft_tmp ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2004-05-04 22:28:15 +04:00
2015-02-23 23:11:00 +03:00
/* Load lvmlocal.conf */
if ( * cmd - > system_dir & & ! _load_config_file ( cmd , " " , 1 ) )
return_0 ;
2011-09-02 05:32:08 +04:00
/* Doesn't change cmd->cft */
2004-05-04 22:28:15 +04:00
if ( ! _init_tag_configs ( cmd ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2004-05-04 22:28:15 +04:00
2011-09-02 05:32:08 +04:00
/* 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 ) ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2004-05-04 22:28:15 +04:00
2011-09-02 05:32:08 +04:00
/* Finally we can make the proper, fully-merged, cmd->cft */
if ( cft_cmdline )
cmd - > cft = dm_config_insert_cascaded_tree ( cft_cmdline , cmd - > cft ) ;
2004-05-04 22:28:15 +04:00
if ( ! _process_config ( cmd ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2004-05-04 22:28:15 +04:00
2014-05-19 15:59:23 +04:00
if ( ! _init_profiles ( cmd ) )
return_0 ;
2013-06-12 14:08:56 +04:00
if ( ! ( cmd - > dev_types = create_dev_types ( cmd - > proc_dir ,
2015-07-08 12:22:24 +03:00
find_config_tree_array ( cmd , devices_types_CFG , NULL ) ) ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2013-06-12 14:08:56 +04:00
2004-05-04 22:28:15 +04:00
if ( ! _init_dev_cache ( cmd ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2004-05-04 22:28:15 +04:00
if ( ! _init_formats ( cmd ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2004-05-04 22:28:15 +04:00
2018-05-03 00:58:49 +03:00
if ( ! lvmcache_init ( cmd ) )
return_0 ;
2008-04-08 16:49:21 +04:00
if ( ! init_lvmcache_orphans ( cmd ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2008-04-08 16:49:21 +04:00
2004-05-05 01:25:57 +04:00
if ( ! _init_segtypes ( cmd ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2004-05-05 01:25:57 +04:00
2010-09-09 17:07:13 +04:00
if ( ! _init_backup ( cmd ) )
2014-03-24 23:31:14 +04:00
return_0 ;
2010-09-09 17:07:13 +04:00
2015-07-30 10:59:39 +03:00
cmd - > initialized . config = 1 ;
2009-07-16 03:57:54 +04:00
2015-07-30 11:34:10 +03:00
if ( cmd - > initialized . connections & & ! init_connections ( cmd ) )
return_0 ;
2015-07-31 11:20:33 +03:00
if ( ! refresh_filters ( cmd ) )
2015-07-30 11:34:10 +03:00
return_0 ;
2009-07-16 03:57:54 +04:00
reset_lvm_errno ( 1 ) ;
2004-05-04 22:28:15 +04:00
return 1 ;
}
2002-11-18 17:01:16 +03:00
void destroy_toolcontext ( struct cmd_context * cmd )
{
2011-09-02 05:32:08 +04:00
struct dm_config_tree * cft_cmdline ;
2013-08-29 02:55:14 +04:00
int flags ;
2011-09-02 05:32:08 +04:00
2013-06-03 01:27:34 +04:00
if ( cmd - > dump_filter & & cmd - > filter & & cmd - > filter - > dump & &
2018-04-20 18:43:50 +03:00
! cmd - > filter - > dump ( cmd - > filter , 1 ) )
2013-06-03 01:27:34 +04:00
stack ;
2002-11-18 17:01:16 +03:00
2005-05-17 17:46:38 +04:00
archive_exit ( cmd ) ;
backup_exit ( cmd ) ;
2014-03-22 01:26:39 +04:00
lvmcache_destroy ( cmd , 0 , 0 ) ;
2018-02-07 00:18:11 +03:00
label_scan_destroy ( cmd ) ;
2002-11-18 17:01:16 +03:00
label_exit ( ) ;
2004-05-05 01:25:57 +04:00
_destroy_segtypes ( & cmd - > segtypes ) ;
2010-04-29 05:38:12 +04:00
_destroy_formats ( cmd , & cmd - > formats ) ;
2014-10-02 14:00:57 +04:00
_destroy_filters ( cmd ) ;
2009-07-08 22:12:08 +04:00
if ( cmd - > mem )
dm_pool_destroy ( cmd - > mem ) ;
2002-11-18 17:01:16 +03:00
dev_cache_exit ( ) ;
2013-06-12 14:08:56 +04:00
_destroy_dev_types ( cmd ) ;
2004-05-04 22:28:15 +04:00
_destroy_tags ( cmd ) ;
2011-09-02 05:59:07 +04:00
2013-06-25 14:25:43 +04:00
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 ) ;
2009-07-08 22:12:08 +04:00
if ( cmd - > libmem )
dm_pool_destroy ( cmd - > libmem ) ;
2011-05-07 17:50:11 +04:00
2012-10-12 18:52:38 +04:00
# ifndef VALGRIND_POOL
2011-05-07 17:50:11 +04:00
if ( cmd - > linebuffer ) {
/* Reset stream buffering to defaults */
2013-08-29 02:55:14 +04:00
if ( is_valid_fd ( STDIN_FILENO ) & &
( ( flags = fcntl ( STDIN_FILENO , F_GETFL ) ) > 0 ) & &
( flags & O_ACCMODE ) ! = O_WRONLY ) {
2016-07-08 17:47:51 +03:00
if ( reopen_standard_stream ( & stdin , " r " ) )
2012-08-27 15:07:07 +04:00
setlinebuf ( stdin ) ;
2016-07-08 17:47:51 +03:00
else
2012-08-27 15:07:07 +04:00
cmd - > linebuffer = NULL ; /* Leave buffer in place (deliberate leak) */
}
2012-08-26 03:19:52 +04:00
2013-08-29 02:55:14 +04:00
if ( is_valid_fd ( STDOUT_FILENO ) & &
( ( flags = fcntl ( STDOUT_FILENO , F_GETFL ) ) > 0 ) & &
( flags & O_ACCMODE ) ! = O_RDONLY ) {
2016-07-08 17:47:51 +03:00
if ( reopen_standard_stream ( & stdout , " w " ) )
2012-08-27 15:07:07 +04:00
setlinebuf ( stdout ) ;
2016-07-08 17:47:51 +03:00
else
2012-08-27 15:07:07 +04:00
cmd - > linebuffer = NULL ; /* Leave buffer in place (deliberate leak) */
}
2012-08-26 03:19:52 +04:00
2011-05-07 17:50:11 +04:00
dm_free ( cmd - > linebuffer ) ;
}
2012-10-12 18:52:38 +04:00
# endif
2005-10-17 03:03:59 +04:00
dm_free ( cmd ) ;
2002-11-18 17:01:16 +03:00
2012-10-12 18:50:38 +04:00
lvmetad_release_token ( ) ;
lvmetad_disconnect ( ) ;
2015-05-09 02:59:18 +03:00
lvmpolld_disconnect ( ) ;
2012-10-12 18:50:38 +04:00
2003-07-05 02:34:56 +04:00
release_log_memory ( ) ;
2005-10-17 22:21:05 +04:00
activation_exit ( ) ;
2010-05-06 02:37:52 +04:00
reset_log_duplicated ( ) ;
2002-11-18 17:01:16 +03:00
fin_log ( ) ;
fin_syslog ( ) ;
2009-07-16 03:57:54 +04:00
reset_lvm_errno ( 0 ) ;
2002-11-18 17:01:16 +03:00
}