2001-12-17 22:46:10 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2018-01-05 05:31:28 +03:00
* Copyright ( C ) 2004 - 2018 Red Hat , Inc . All rights reserved .
2001-12-17 22:46:10 +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
2001-12-17 22:46:10 +03:00
*/
2002-11-18 17:04:08 +03:00
# include "lib.h"
2002-01-11 02:21:07 +03:00
# include "metadata.h"
2001-12-17 22:46:10 +03:00
# include "import-export.h"
2018-01-02 23:40:18 +03:00
# include "toolcontext.h"
2002-11-18 17:04:08 +03:00
/* FIXME Use tidier inclusion method */
static struct text_vg_version_ops * ( _text_vsn_list [ 2 ] ) ;
2008-03-13 15:33:22 +03:00
static int _text_import_initialised = 0 ;
2010-08-03 17:06:35 +04:00
static void _init_text_import ( void )
2008-03-13 15:33:22 +03:00
{
if ( _text_import_initialised )
return ;
_text_vsn_list [ 0 ] = text_vg_vsn1_init ( ) ;
_text_vsn_list [ 1 ] = NULL ;
_text_import_initialised = 1 ;
}
2018-01-03 19:00:52 +03:00
struct import_vgsummary_params {
const struct format_type * fmt ;
struct dm_config_tree * cft ;
int checksum_only ;
struct lvmcache_vgsummary * vgsummary ;
2018-01-09 04:50:23 +03:00
lvm_callback_fn_t process_vgsummary_fn ;
void * process_vgsummary_context ;
2018-01-05 05:31:28 +03:00
int ret ;
2018-01-03 19:00:52 +03:00
} ;
2018-01-10 22:50:53 +03:00
static void _import_vgsummary ( int failed , void * context , const void * data )
2018-01-03 19:00:52 +03:00
{
2018-01-05 17:24:10 +03:00
struct import_vgsummary_params * ivsp = context ;
2018-01-03 19:00:52 +03:00
struct text_vg_version_ops * * vsn ;
2018-01-06 03:33:09 +03:00
if ( failed ) {
ivsp - > ret = 0 ;
goto_out ;
}
2018-01-05 05:31:28 +03:00
if ( ivsp - > checksum_only )
2018-01-03 19:00:52 +03:00
/* Checksum matches already-cached content - no need to reparse. */
goto out ;
/*
* Find a set of version functions that can read this file
*/
for ( vsn = & _text_vsn_list [ 0 ] ; * vsn ; vsn + + ) {
if ( ! ( * vsn ) - > check_version ( ivsp - > cft ) )
continue ;
2018-01-05 05:31:28 +03:00
if ( ! ( * vsn ) - > read_vgsummary ( ivsp - > fmt , ivsp - > cft , ivsp - > vgsummary ) ) {
ivsp - > ret = 0 ;
2018-01-03 19:00:52 +03:00
goto_out ;
2018-01-05 05:31:28 +03:00
}
2018-01-03 19:00:52 +03:00
2018-01-05 05:31:28 +03:00
goto out ;
2018-01-03 19:00:52 +03:00
}
2018-01-05 05:31:28 +03:00
/* Nothing found */
ivsp - > ret = 0 ;
2018-01-03 19:00:52 +03:00
out :
config_destroy ( ivsp - > cft ) ;
2018-01-09 04:50:23 +03:00
if ( ivsp - > ret & & ivsp - > process_vgsummary_fn )
ivsp - > process_vgsummary_fn ( 0 , ivsp - > process_vgsummary_context , NULL ) ;
2018-01-03 19:00:52 +03:00
}
2015-03-06 12:24:26 +03:00
/*
* Find out vgname on a given device .
*/
2016-02-09 22:32:26 +03:00
int text_vgsummary_import ( const struct format_type * fmt ,
2017-12-07 06:34:59 +03:00
struct device * dev , dev_io_reason_t reason ,
2015-03-19 02:43:02 +03:00
off_t offset , uint32_t size ,
off_t offset2 , uint32_t size2 ,
checksum_fn_t checksum_fn ,
int checksum_only ,
2018-01-09 04:50:23 +03:00
struct lvmcache_vgsummary * vgsummary ,
lvm_callback_fn_t process_vgsummary_fn ,
void * process_vgsummary_context )
2006-04-11 17:55:59 +04:00
{
2018-01-03 19:00:52 +03:00
struct import_vgsummary_params * ivsp ;
2006-04-11 17:55:59 +04:00
2008-03-13 15:33:22 +03:00
_init_text_import ( ) ;
2006-04-11 17:55:59 +04:00
2018-01-03 19:00:52 +03:00
if ( ! ( ivsp = dm_pool_zalloc ( fmt - > cmd - > mem , sizeof ( * ivsp ) ) ) ) {
log_error ( " Failed to allocate import_vgsummary_params struct. " ) ;
return 0 ;
}
if ( ! ( ivsp - > cft = config_open ( CONFIG_FILE_SPECIAL , NULL , 0 ) ) )
2015-03-19 02:43:02 +03:00
return_0 ;
2006-04-11 17:55:59 +04:00
2018-01-03 19:00:52 +03:00
ivsp - > fmt = fmt ;
ivsp - > checksum_only = checksum_only ;
ivsp - > vgsummary = vgsummary ;
2018-01-09 04:50:23 +03:00
ivsp - > process_vgsummary_fn = process_vgsummary_fn ;
ivsp - > process_vgsummary_context = process_vgsummary_context ;
2018-01-05 05:31:28 +03:00
ivsp - > ret = 1 ;
2018-01-03 19:00:52 +03:00
2018-01-06 03:33:09 +03:00
if ( ! dev ) {
if ( ! config_file_read ( fmt - > cmd - > mem , ivsp - > cft ) ) {
log_error ( " Couldn't read volume group metadata. " ) ;
ivsp - > ret = 0 ;
}
_import_vgsummary ( ! ivsp - > ret , ivsp , NULL ) ;
} else if ( ! config_file_read_fd ( fmt - > cmd - > mem , ivsp - > cft , dev , reason , offset , size ,
2018-01-03 19:00:52 +03:00
offset2 , size2 , checksum_fn ,
vgsummary - > mda_checksum ,
2018-01-06 03:33:09 +03:00
checksum_only , 1 , & _import_vgsummary , ivsp ) ) {
2018-01-03 19:00:52 +03:00
log_error ( " Couldn't read volume group metadata. " ) ;
return 0 ;
}
2018-01-05 05:31:28 +03:00
return ivsp - > ret ;
2018-01-03 19:00:52 +03:00
}
struct cached_vg_fmtdata {
uint32_t cached_mda_checksum ;
size_t cached_mda_size ;
} ;
struct import_vg_params {
struct format_instance * fid ;
struct dm_config_tree * cft ;
int single_device ;
int skip_parse ;
unsigned * use_previous_vg ;
struct volume_group * vg ;
uint32_t checksum ;
uint32_t total_size ;
time_t * when ;
struct cached_vg_fmtdata * * vg_fmtdata ;
char * * desc ;
} ;
2018-01-10 22:50:53 +03:00
static void _import_vg ( int failed , void * context , const void * data )
2018-01-03 19:00:52 +03:00
{
2018-01-05 17:24:10 +03:00
struct import_vg_params * ivp = context ;
2018-01-03 19:00:52 +03:00
struct text_vg_version_ops * * vsn ;
ivp - > vg = NULL ;
if ( ivp - > skip_parse ) {
if ( ivp - > use_previous_vg )
* ivp - > use_previous_vg = 1 ;
2015-03-19 02:43:02 +03:00
goto out ;
}
2015-03-06 12:24:26 +03:00
2008-01-30 17:00:02 +03:00
/*
2006-04-11 17:55:59 +04:00
* Find a set of version functions that can read this file
*/
for ( vsn = & _text_vsn_list [ 0 ] ; * vsn ; vsn + + ) {
2018-01-03 19:00:52 +03:00
if ( ! ( * vsn ) - > check_version ( ivp - > cft ) )
2006-04-11 17:55:59 +04:00
continue ;
2018-01-03 19:00:52 +03:00
if ( ! ( ivp - > vg = ( * vsn ) - > read_vg ( ivp - > fid , ivp - > cft , ivp - > single_device , 0 ) ) )
2006-04-11 17:55:59 +04:00
goto_out ;
2018-01-03 19:00:52 +03:00
( * vsn ) - > read_desc ( ivp - > vg - > vgmem , ivp - > cft , ivp - > when , ivp - > desc ) ;
2006-04-11 17:55:59 +04:00
break ;
}
2018-01-03 19:00:52 +03:00
if ( ivp - > vg & & ivp - > vg_fmtdata & & * ivp - > vg_fmtdata ) {
( * ivp - > vg_fmtdata ) - > cached_mda_size = ivp - > total_size ;
( * ivp - > vg_fmtdata ) - > cached_mda_checksum = ivp - > checksum ;
}
2006-04-11 17:55:59 +04:00
2018-01-03 19:00:52 +03:00
if ( ivp - > use_previous_vg )
* ivp - > use_previous_vg = 0 ;
out :
config_destroy ( ivp - > cft ) ;
}
2015-03-19 02:43:02 +03:00
2002-11-18 17:04:08 +03:00
struct volume_group * text_vg_import_fd ( struct format_instance * fid ,
const char * file ,
2015-03-19 02:43:02 +03:00
struct cached_vg_fmtdata * * vg_fmtdata ,
unsigned * use_previous_vg ,
2012-02-29 06:35:35 +04:00
int single_device ,
2017-12-07 06:34:59 +03:00
struct device * dev , int primary_mda ,
2002-11-18 17:04:08 +03:00
off_t offset , uint32_t size ,
off_t offset2 , uint32_t size2 ,
checksum_fn_t checksum_fn ,
uint32_t checksum ,
time_t * when , char * * desc )
2002-01-10 14:18:08 +03:00
{
2018-01-03 19:00:52 +03:00
struct import_vg_params * ivp ;
2002-01-10 14:18:08 +03:00
2015-03-19 02:43:02 +03:00
if ( vg_fmtdata & & ! * vg_fmtdata & &
! ( * vg_fmtdata = dm_pool_zalloc ( fid - > mem , sizeof ( * * vg_fmtdata ) ) ) ) {
log_error ( " Failed to allocate VG fmtdata for text format. " ) ;
return NULL ;
}
2018-01-03 19:00:52 +03:00
if ( ! ( ivp = dm_pool_zalloc ( fid - > fmt - > cmd - > mem , sizeof ( * ivp ) ) ) ) {
log_error ( " Failed to allocate import_vgsummary_params struct. " ) ;
return NULL ;
}
2002-01-10 14:18:08 +03:00
2018-01-03 19:00:52 +03:00
_init_text_import ( ) ;
2002-01-10 19:48:28 +03:00
2018-01-03 19:00:52 +03:00
ivp - > fid = fid ;
ivp - > when = when ;
* ivp - > when = 0 ;
ivp - > desc = desc ;
* ivp - > desc = NULL ;
ivp - > single_device = single_device ;
ivp - > use_previous_vg = use_previous_vg ;
ivp - > checksum = checksum ;
ivp - > total_size = size + size2 ;
ivp - > vg_fmtdata = vg_fmtdata ;
if ( ! ( ivp - > cft = config_open ( CONFIG_FILE_SPECIAL , file , 0 ) ) )
2006-05-10 21:51:02 +04:00
return_NULL ;
2002-01-10 14:18:08 +03:00
2015-03-19 02:43:02 +03:00
/* Does the metadata match the already-cached VG? */
2018-01-03 19:00:52 +03:00
ivp - > skip_parse = vg_fmtdata & &
( ( * vg_fmtdata ) - > cached_mda_checksum = = checksum ) & &
( ( * vg_fmtdata ) - > cached_mda_size = = ivp - > total_size ) ;
2012-03-26 15:35:26 +04:00
2018-01-03 19:00:52 +03:00
if ( ! dev & & ! config_file_read ( fid - > mem , ivp - > cft ) ) {
config_destroy ( ivp - > cft ) ;
return_NULL ;
2001-12-17 22:46:10 +03:00
}
2002-04-24 22:20:51 +04:00
2018-01-06 03:33:09 +03:00
if ( dev ) {
if ( ! config_file_read_fd ( fid - > mem , ivp - > cft , dev , MDA_CONTENT_REASON ( primary_mda ) , offset , size ,
2018-01-03 19:00:52 +03:00
offset2 , size2 , checksum_fn , checksum ,
2018-01-06 03:33:09 +03:00
ivp - > skip_parse , 1 , & _import_vg , ivp ) ) {
config_destroy ( ivp - > cft ) ;
return_NULL ;
}
} else
_import_vg ( 0 , ivp , NULL ) ;
2015-03-19 02:43:02 +03:00
2018-01-03 19:00:52 +03:00
return ivp - > vg ;
2001-12-17 22:46:10 +03:00
}
2002-11-18 17:04:08 +03:00
struct volume_group * text_vg_import_file ( struct format_instance * fid ,
const char * file ,
time_t * when , char * * desc )
2002-02-11 14:43:17 +03:00
{
2017-12-07 06:34:59 +03:00
return text_vg_import_fd ( fid , file , NULL , NULL , 0 , NULL , 0 , ( off_t ) 0 , 0 , ( off_t ) 0 , 0 , NULL , 0 ,
2002-11-18 17:04:08 +03:00
when , desc ) ;
2001-12-17 22:46:10 +03:00
}
2008-04-02 02:40:13 +04:00
2015-06-10 17:25:57 +03:00
static struct volume_group * _import_vg_from_config_tree ( const struct dm_config_tree * cft ,
struct format_instance * fid ,
unsigned allow_lvmetad_extensions )
2008-04-02 02:40:13 +04:00
{
struct volume_group * vg = NULL ;
struct text_vg_version_ops * * vsn ;
2011-06-17 18:39:10 +04:00
int vg_missing ;
2008-04-02 02:40:13 +04:00
_init_text_import ( ) ;
for ( vsn = & _text_vsn_list [ 0 ] ; * vsn ; vsn + + ) {
if ( ! ( * vsn ) - > check_version ( cft ) )
continue ;
2010-03-17 05:11:18 +03:00
/*
* The only path to this point uses cached vgmetadata ,
* so it can use cached PV state too .
*/
2015-06-10 17:25:57 +03:00
if ( ! ( vg = ( * vsn ) - > read_vg ( fid , cft , 1 , allow_lvmetad_extensions ) ) )
2008-04-02 02:40:13 +04:00
stack ;
2011-06-17 18:39:10 +04:00
else if ( ( vg_missing = vg_missing_pv_count ( vg ) ) ) {
log_verbose ( " There are %d physical volumes missing. " ,
vg_missing ) ;
vg_mark_partial_lvs ( vg , 1 ) ;
/* FIXME: move this code inside read_vg() */
}
2008-04-02 02:40:13 +04:00
break ;
}
return vg ;
}
2015-06-10 17:25:57 +03:00
struct volume_group * import_vg_from_config_tree ( const struct dm_config_tree * cft ,
struct format_instance * fid )
{
return _import_vg_from_config_tree ( cft , fid , 0 ) ;
}
struct volume_group * import_vg_from_lvmetad_config_tree ( const struct dm_config_tree * cft ,
struct format_instance * fid )
{
return _import_vg_from_config_tree ( cft , fid , 1 ) ;
}