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 ;
}
2006-04-11 17:55:59 +04:00
const char * 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 , uint32_t checksum ,
2009-11-25 01:55:55 +03:00
struct id * vgid , uint64_t * vgstatus ,
2006-04-13 21:32:24 +04:00
char * * creation_host )
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 ;
2006-05-10 20:42:03 +04:00
const char * vgname = NULL ;
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 ) ) )
2006-05-10 21:49:25 +04:00
return_NULL ;
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 ,
2012-03-26 15:35:26 +04:00
offset2 , size2 , checksum_fn , checksum , 0 ) ) ) {
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
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 ;
2006-04-13 21:32:24 +04:00
if ( ! ( vgname = ( * vsn ) - > read_vgname ( fmt , cft , vgid , vgstatus ,
creation_host ) ) )
2006-04-11 17:55:59 +04:00
goto_out ;
break ;
}
out :
2013-06-25 14:25:43 +04:00
config_destroy ( cft ) ;
2006-04-11 17:55:59 +04:00
return vgname ;
}
2002-11-18 17:04:08 +03:00
struct volume_group * text_vg_import_fd ( struct format_instance * fid ,
const char * file ,
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
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
2012-03-26 15:35:26 +04:00
skip_parse = fid - > vg & & ( fid - > mda_checksum = = checksum ) & &
( fid - > mda_size = = ( size + size2 ) ) ;
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 ) {
vg = fid - > vg ;
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
2012-02-29 06:35:35 +04:00
if ( ! ( vg = ( * vsn ) - > read_vg ( fid , cft , single_device ) ) )
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
2012-03-26 15:35:26 +04:00
if ( vg & & ( ! fid - > vg | | ( vg - > seqno > fid - > vg - > seqno ) ) ) {
/*
* Remember vg pointer to newest VG for reuse .
* NOTE : _vg_read ( ) will not release same VG
*/
fid - > vg = vg ;
fid - > mda_size = ( size + size2 ) ;
fid - > mda_checksum = checksum ;
}
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
{
2012-02-29 06:35:35 +04:00
return text_vg_import_fd ( fid , file , 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
2011-08-30 18:55:15 +04:00
struct volume_group * import_vg_from_config_tree ( const struct dm_config_tree * cft ,
2011-01-10 16:13:42 +03:00
struct format_instance * fid )
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 .
*/
if ( ! ( vg = ( * vsn ) - > read_vg ( fid , cft , 1 ) ) )
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 ;
}