2003-10-16 00:17:19 +04:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2003 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2007 Red Hat , Inc . All rights reserved .
2003-10-16 00:17:19 +04:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
2003-10-16 00:17:19 +04:00
*
2004-03-30 23:35:44 +04:00
* 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 .
2003-10-16 00:17:19 +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 ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2003-10-16 00:17:19 +04:00
*/
# include "tools.h"
2013-07-08 17:34:27 +04:00
static int _get_vsn ( struct cmd_context * cmd , uint16_t * version_int )
2013-03-05 20:48:29 +04:00
{
2013-07-08 15:45:37 +04:00
const char * atversion = arg_str_value ( cmd , atversion_ARG , LVM_VERSION ) ;
unsigned int major , minor , patchlevel ;
2013-03-05 20:48:29 +04:00
2013-07-08 15:45:37 +04:00
if ( sscanf ( atversion , " %u.%u.%u " , & major , & minor , & patchlevel ) ! = 3 ) {
2013-03-05 20:48:29 +04:00
log_error ( " Incorrect version format. " ) ;
return 0 ;
}
2013-07-08 17:34:27 +04:00
* version_int = vsn ( major , minor , patchlevel ) ;
2013-03-05 20:48:29 +04:00
return 1 ;
}
2013-07-08 17:34:27 +04:00
static struct cft_check_handle * _get_cft_check_handle ( struct cmd_context * cmd , struct dm_config_tree * cft )
2013-06-26 16:53:57 +04:00
{
2013-07-08 17:34:27 +04:00
struct cft_check_handle * handle ;
struct dm_pool * mem ;
if ( cft = = cmd - > cft ) {
mem = cmd - > libmem ;
handle = cmd - > cft_check_handle ;
} else {
mem = cft - > mem ;
handle = NULL ;
}
2013-06-26 16:53:57 +04:00
if ( ! handle ) {
2013-07-08 17:34:27 +04:00
if ( ! ( handle = dm_pool_zalloc ( mem , sizeof ( struct cft_check_handle ) ) ) ) {
2013-06-26 16:53:57 +04:00
log_error ( " Configuration check handle allocation failed. " ) ;
return NULL ;
}
2013-07-08 17:34:27 +04:00
handle - > cft = cft ;
if ( cft = = cmd - > cft )
cmd - > cft_check_handle = handle ;
2013-06-26 16:53:57 +04:00
}
return handle ;
}
2013-07-08 17:34:27 +04:00
static int _do_def_check ( struct cmd_context * cmd , struct dm_config_tree * cft ,
struct cft_check_handle * * cft_check_handle )
2013-07-08 16:13:09 +04:00
{
struct cft_check_handle * handle ;
2013-07-08 17:34:27 +04:00
if ( ! ( handle = _get_cft_check_handle ( cmd , cft ) ) )
2013-07-08 16:13:09 +04:00
return 0 ;
handle - > force_check = 1 ;
handle - > skip_if_checked = 1 ;
handle - > suppress_messages = 1 ;
config_def_check ( cmd , handle ) ;
* cft_check_handle = handle ;
return 1 ;
}
2013-07-08 17:34:27 +04:00
static int _merge_config_cascade ( struct cmd_context * cmd , struct dm_config_tree * cft_cascaded ,
struct dm_config_tree * * cft_merged )
{
if ( ! cft_cascaded )
return 1 ;
if ( ! * cft_merged & & ! ( * cft_merged = config_open ( CONFIG_MERGED_FILES , NULL , 0 ) ) )
return_0 ;
if ( ! _merge_config_cascade ( cmd , cft_cascaded - > cascade , cft_merged ) )
return_0 ;
return merge_config_tree ( cmd , * cft_merged , cft_cascaded , CONFIG_MERGE_TYPE_RAW ) ;
}
2003-10-16 00:17:19 +04:00
int dumpconfig ( struct cmd_context * cmd , int argc , char * * argv )
{
2009-11-03 18:50:42 +03:00
const char * file = arg_str_value ( cmd , file_ARG , NULL ) ;
2013-03-05 20:48:29 +04:00
const char * type = arg_str_value ( cmd , configtype_ARG , " current " ) ;
struct config_def_tree_spec tree_spec = { 0 } ;
2013-07-08 15:45:37 +04:00
struct dm_config_tree * cft = NULL ;
2013-07-08 16:13:09 +04:00
struct cft_check_handle * cft_check_handle = NULL ;
2013-03-05 20:48:29 +04:00
int r = ECMD_PROCESSED ;
if ( arg_count ( cmd , configtype_ARG ) & & arg_count ( cmd , validate_ARG ) ) {
log_error ( " Only one of --type and --validate permitted. " ) ;
return EINVALID_CMD_LINE ;
}
if ( arg_count ( cmd , atversion_ARG ) & & ! arg_count ( cmd , configtype_ARG ) ) {
log_error ( " --atversion requires --type " ) ;
return EINVALID_CMD_LINE ;
}
2013-03-06 12:35:33 +04:00
if ( arg_count ( cmd , ignoreadvanced_ARG ) )
tree_spec . ignoreadvanced = 1 ;
if ( arg_count ( cmd , ignoreunsupported_ARG ) )
tree_spec . ignoreunsupported = 1 ;
2013-07-08 15:45:37 +04:00
if ( ! strcmp ( type , " current " ) ) {
if ( arg_count ( cmd , atversion_ARG ) ) {
log_error ( " --atversion has no effect with --type current " ) ;
return EINVALID_CMD_LINE ;
}
if ( ( tree_spec . ignoreadvanced | | tree_spec . ignoreunsupported ) ) {
log_error ( " --ignoreadvanced and --ignoreunsupported has "
" no effect with --type current " ) ;
return EINVALID_CMD_LINE ;
}
}
if ( ! _get_vsn ( cmd , & tree_spec . version ) )
return EINVALID_CMD_LINE ;
2013-07-08 17:34:27 +04:00
/*
* Set the ' cft ' to work with based on whether we need the plain
* config tree or merged config tree cascade if - - mergedconfig is used .
*/
if ( arg_count ( cmd , mergedconfig_ARG ) & & cmd - > cft - > cascade ) {
if ( ! _merge_config_cascade ( cmd , cmd - > cft , & cft ) ) {
log_error ( " Failed to merge configuration. " ) ;
r = ECMD_FAILED ;
goto out ;
}
} else
cft = cmd - > cft ;
2013-03-05 20:48:29 +04:00
if ( arg_count ( cmd , validate_ARG ) ) {
2013-07-08 17:34:27 +04:00
if ( ! ( cft_check_handle = _get_cft_check_handle ( cmd , cft ) ) )
2013-06-26 16:53:57 +04:00
return ECMD_FAILED ;
cft_check_handle - > force_check = 1 ;
cft_check_handle - > skip_if_checked = 1 ;
cft_check_handle - > suppress_messages = 0 ;
if ( config_def_check ( cmd , cft_check_handle ) ) {
2013-03-05 20:48:29 +04:00
log_print ( " LVM configuration valid. " ) ;
2013-07-08 17:34:27 +04:00
goto out ;
2013-03-05 20:48:29 +04:00
} else {
log_error ( " LVM configuration invalid. " ) ;
2013-07-08 17:34:27 +04:00
r = ECMD_FAILED ;
goto out ;
2013-03-05 20:48:29 +04:00
}
}
if ( ! strcmp ( type , " current " ) ) {
tree_spec . type = CFG_DEF_TREE_CURRENT ;
2013-07-08 17:34:27 +04:00
if ( ! _do_def_check ( cmd , cft , & cft_check_handle ) ) {
r = ECMD_FAILED ;
goto_out ;
}
2013-03-05 20:48:29 +04:00
}
2013-07-08 16:13:09 +04:00
else if ( ! strcmp ( type , " missing " ) ) {
2013-03-05 20:48:29 +04:00
tree_spec . type = CFG_DEF_TREE_MISSING ;
2013-07-08 17:34:27 +04:00
if ( ! _do_def_check ( cmd , cft , & cft_check_handle ) ) {
r = ECMD_FAILED ;
goto_out ;
}
2013-07-08 16:13:09 +04:00
}
else if ( ! strcmp ( type , " default " ) ) {
tree_spec . type = CFG_DEF_TREE_DEFAULT ;
/* default type does not require check status */
}
else if ( ! strcmp ( type , " new " ) ) {
2013-03-05 20:48:29 +04:00
tree_spec . type = CFG_DEF_TREE_NEW ;
2013-07-08 16:13:09 +04:00
/* new type does not require check status */
}
2013-07-09 11:57:46 +04:00
else if ( ! strcmp ( type , " profilable " ) ) {
tree_spec . type = CFG_DEF_TREE_PROFILABLE ;
/* profilable type does not require check status */
}
2013-03-05 20:48:29 +04:00
else {
log_error ( " Incorrect type of configuration specified. "
" Expected one of: current, default, missing, new. " ) ;
2013-07-08 17:34:27 +04:00
r = EINVALID_CMD_LINE ;
goto out ;
2013-03-05 20:48:29 +04:00
}
2013-07-08 16:13:09 +04:00
if ( cft_check_handle )
tree_spec . check_status = cft_check_handle - > status ;
2013-07-08 17:34:27 +04:00
if ( tree_spec . type ! = CFG_DEF_TREE_CURRENT )
2013-03-05 20:48:29 +04:00
cft = config_def_create_tree ( & tree_spec ) ;
2013-03-05 21:21:13 +04:00
if ( ! config_write ( cft , arg_count ( cmd , withcomments_ARG ) ,
arg_count ( cmd , withversions_ARG ) ,
file , argc , argv ) ) {
2009-09-15 02:47:49 +04:00
stack ;
2013-03-05 20:48:29 +04:00
r = ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2013-07-08 17:34:27 +04:00
out :
if ( cft & & ( cft ! = cmd - > cft ) )
2013-03-05 20:48:29 +04:00
dm_pool_destroy ( cft - > mem ) ;
2013-07-08 15:45:37 +04:00
/*
* The cmd - > cft ( the " current " tree ) is destroyed
* together with cmd context destroy . . .
*/
2013-03-05 20:48:29 +04:00
return r ;
2003-10-16 00:17:19 +04:00
}