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 .
2008-04-02 02:40:13 +04:00
* Copyright ( C ) 2004 - 2008 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 ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 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"
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 ;
}
2015-03-06 12:24:26 +03:00
/*
* Find out vgname on a given device .
*/
2015-03-19 02:43:02 +03:00
int text_vgname_import ( const struct format_type * fmt ,
struct device * dev ,
off_t offset , uint32_t size ,
off_t offset2 , uint32_t size2 ,
checksum_fn_t checksum_fn ,
int checksum_only ,
struct lvmcache_vgsummary * vgsummary )
2006-04-11 17:55:59 +04:00
{
2011-08-30 18:55:15 +04:00
struct dm_config_tree * cft ;
2006-04-11 17:55:59 +04:00
struct text_vg_version_ops * * vsn ;
2015-03-19 02:43:02 +03:00
int r = 0 ;
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
2014-05-19 12:58:28 +04:00
if ( ! ( 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
2011-12-19 01:56:03 +04:00
if ( ( ! dev & & ! config_file_read ( cft ) ) | |
( dev & & ! config_file_read_fd ( cft , dev , offset , size ,
2015-03-19 02:43:02 +03:00
offset2 , size2 , checksum_fn ,
vgsummary - > mda_checksum ,
checksum_only ) ) ) {
2014-10-07 04:04:09 +04:00
log_error ( " Couldn't read volume group metadata. " ) ;
goto out ;
}
2006-04-11 17:55:59 +04:00
2015-03-19 02:43:02 +03:00
if ( checksum_only ) {
/* Checksum matches already-cached content - no need to reparse. */
r = 1 ;
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 + + ) {
if ( ! ( * vsn ) - > check_version ( cft ) )
continue ;
2015-03-19 02:43:02 +03:00
if ( ! ( * vsn ) - > read_vgname ( fmt , cft , vgsummary ) )
2006-04-11 17:55:59 +04:00
goto_out ;
2015-03-19 02:43:02 +03:00
r = 1 ;
2006-04-11 17:55:59 +04:00
break ;
}
out :
2013-06-25 14:25:43 +04:00
config_destroy ( cft ) ;
2015-03-19 02:43:02 +03:00
return r ;
2006-04-11 17:55:59 +04:00
}
2015-03-19 02:43:02 +03:00
struct cached_vg_fmtdata {
uint32_t cached_mda_checksum ;
size_t cached_mda_size ;
} ;
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 ,
2003-07-05 02:34:56 +04:00
struct device * dev ,
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
{
2002-11-18 17:04:08 +03:00
struct volume_group * vg = NULL ;
2011-08-30 18:55:15 +04:00
struct dm_config_tree * cft ;
2002-11-18 17:04:08 +03:00
struct text_vg_version_ops * * vsn ;
2012-03-26 15:35:26 +04:00
int skip_parse ;
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 ;
}
2008-03-13 15:33:22 +03:00
_init_text_import ( ) ;
2002-01-10 14:18:08 +03:00
2002-11-18 17:04:08 +03:00
* desc = NULL ;
* when = 0 ;
2002-01-10 19:48:28 +03:00
2014-05-19 12:58:28 +04:00
if ( ! ( 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? */
skip_parse = vg_fmtdata & &
( ( * vg_fmtdata ) - > cached_mda_checksum = = checksum ) & &
( ( * vg_fmtdata ) - > cached_mda_size = = ( size + size2 ) ) ;
2012-03-26 15:35:26 +04:00
2011-12-19 01:56:03 +04:00
if ( ( ! dev & & ! config_file_read ( cft ) ) | |
( dev & & ! config_file_read_fd ( cft , dev , offset , size ,
2012-03-26 15:35:26 +04:00
offset2 , size2 , checksum_fn , checksum ,
skip_parse ) ) )
2015-03-06 13:12:16 +03:00
goto_out ;
2002-02-01 20:54:39 +03:00
2012-03-26 15:35:26 +04:00
if ( skip_parse ) {
2015-03-19 02:43:02 +03:00
if ( use_previous_vg )
* use_previous_vg = 1 ;
2012-03-26 15:35:26 +04:00
goto out ;
}
2008-01-30 17:00:02 +03:00
/*
2002-11-18 17:04:08 +03:00
* Find a set of version functions that can read this file
2002-07-11 18:21:49 +04:00
*/
2002-11-18 17:04:08 +03:00
for ( vsn = & _text_vsn_list [ 0 ] ; * vsn ; vsn + + ) {
2004-03-08 21:28:45 +03:00
if ( ! ( * vsn ) - > check_version ( cft ) )
2002-11-18 17:04:08 +03:00
continue ;
2002-02-13 16:29:16 +03:00
2015-06-10 17:25:57 +03:00
if ( ! ( vg = ( * vsn ) - > read_vg ( fid , cft , single_device , 0 ) ) )
2008-01-30 16:19:47 +03:00
goto_out ;
2001-12-17 22:46:10 +03:00
2010-03-31 21:23:18 +04:00
( * vsn ) - > read_desc ( vg - > vgmem , cft , when , desc ) ;
2002-11-18 17:04:08 +03:00
break ;
2001-12-17 22:46:10 +03:00
}
2002-04-24 22:20:51 +04:00
2015-03-19 02:43:02 +03:00
if ( vg & & vg_fmtdata & & * vg_fmtdata ) {
( * vg_fmtdata ) - > cached_mda_size = ( size + size2 ) ;
( * vg_fmtdata ) - > cached_mda_checksum = checksum ;
2012-03-26 15:35:26 +04:00
}
2015-03-19 02:43:02 +03:00
if ( use_previous_vg )
* use_previous_vg = 0 ;
2002-11-18 17:04:08 +03:00
out :
2013-06-25 14:25:43 +04:00
config_destroy ( cft ) ;
2002-01-10 14:18:08 +03:00
return 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
{
2015-03-19 02:43:02 +03:00
return text_vg_import_fd ( fid , file , NULL , NULL , 0 , NULL , ( 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 ) ;
}