2002-11-18 17:04:08 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2002 - 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 .
2002-11-18 17:04:08 +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:04:08 +03:00
*/
# include "lib.h"
# include "format-text.h"
# include "layout.h"
# include "label.h"
# include "xlate.h"
2004-05-05 01:25:57 +04:00
# include "lvmcache.h"
2017-12-15 17:57:05 +03:00
# include "toolcontext.h"
2002-11-18 17:04:08 +03:00
# include <sys/stat.h>
# include <fcntl.h>
2010-07-09 19:34:40 +04:00
static int _text_can_handle ( struct labeller * l __attribute__ ( ( unused ) ) ,
2006-12-01 02:11:42 +03:00
void * buf ,
2010-07-09 19:34:40 +04:00
uint64_t sector __attribute__ ( ( unused ) ) )
2002-11-18 17:04:08 +03:00
{
struct label_header * lh = ( struct label_header * ) buf ;
2006-05-10 01:23:51 +04:00
if ( ! strncmp ( ( char * ) lh - > type , LVM2_LABEL , sizeof ( lh - > type ) ) )
2002-11-18 17:04:08 +03:00
return 1 ;
return 0 ;
}
2018-01-04 02:53:00 +03:00
struct dl_setup_baton {
2012-02-10 05:28:27 +04:00
struct disk_locn * pvh_dlocn_xl ;
struct device * dev ;
} ;
2012-02-23 17:11:07 +04:00
static int _da_setup ( struct disk_locn * da , void * baton )
2012-02-10 05:28:27 +04:00
{
2018-01-04 02:53:00 +03:00
struct dl_setup_baton * p = baton ;
2012-02-23 17:11:07 +04:00
p - > pvh_dlocn_xl - > offset = xlate64 ( da - > offset ) ;
p - > pvh_dlocn_xl - > size = xlate64 ( da - > size ) ;
2012-02-10 05:28:27 +04:00
p - > pvh_dlocn_xl + + ;
return 1 ;
}
2013-05-28 14:37:22 +04:00
static int _ba_setup ( struct disk_locn * ba , void * baton )
2013-02-15 14:02:53 +04:00
{
2013-05-28 14:37:22 +04:00
return _da_setup ( ba , baton ) ;
2013-02-15 14:02:53 +04:00
}
2012-02-10 05:28:27 +04:00
static int _mda_setup ( struct metadata_area * mda , void * baton )
{
2018-01-04 02:53:00 +03:00
struct dl_setup_baton * p = baton ;
2012-02-10 05:28:27 +04:00
struct mda_context * mdac = ( struct mda_context * ) mda - > metadata_locn ;
if ( mdac - > area . dev ! = p - > dev )
return 1 ;
p - > pvh_dlocn_xl - > offset = xlate64 ( mdac - > area . start ) ;
p - > pvh_dlocn_xl - > size = xlate64 ( mdac - > area . size ) ;
p - > pvh_dlocn_xl + + ;
return 1 ;
}
2013-02-15 14:02:53 +04:00
static int _dl_null_termination ( void * baton )
{
2018-01-04 02:53:00 +03:00
struct dl_setup_baton * p = baton ;
2013-02-15 14:02:53 +04:00
p - > pvh_dlocn_xl - > offset = xlate64 ( UINT64_C ( 0 ) ) ;
p - > pvh_dlocn_xl - > size = xlate64 ( UINT64_C ( 0 ) ) ;
p - > pvh_dlocn_xl + + ;
return 1 ;
}
2006-12-01 02:11:42 +03:00
static int _text_write ( struct label * label , void * buf )
2002-11-18 17:04:08 +03:00
{
struct label_header * lh = ( struct label_header * ) buf ;
struct pv_header * pvhdr ;
2013-02-15 14:02:53 +04:00
struct pv_header_extension * pvhdr_ext ;
2003-07-05 02:34:56 +04:00
struct lvmcache_info * info ;
2018-01-04 02:53:00 +03:00
struct dl_setup_baton baton ;
2010-07-09 19:34:40 +04:00
char buffer [ 64 ] __attribute__ ( ( aligned ( 8 ) ) ) ;
2013-05-28 14:37:22 +04:00
int ba1 , da1 , mda1 , mda2 ;
2002-11-18 17:04:08 +03:00
2013-02-15 14:02:53 +04:00
/*
* PV header base
*/
2002-11-18 17:04:08 +03:00
/* FIXME Move to where label is created */
2015-08-18 16:21:48 +03:00
strncpy ( label - > type , LVM2_LABEL , sizeof ( label - > type ) ) ;
strncpy ( ( char * ) lh - > type , label - > type , sizeof ( label - > type ) ) ;
2002-11-18 17:04:08 +03:00
2011-02-18 17:34:41 +03:00
pvhdr = ( struct pv_header * ) ( ( char * ) buf + xlate32 ( lh - > offset_xl ) ) ;
2003-07-05 02:34:56 +04:00
info = ( struct lvmcache_info * ) label - > info ;
2012-02-10 05:28:27 +04:00
pvhdr - > device_size_xl = xlate64 ( lvmcache_device_size ( info ) ) ;
memcpy ( pvhdr - > pv_uuid , & lvmcache_device ( info ) - > pvid , sizeof ( struct id ) ) ;
2009-02-21 02:19:28 +03:00
if ( ! id_write_format ( ( const struct id * ) pvhdr - > pv_uuid , buffer ,
sizeof ( buffer ) ) ) {
stack ;
buffer [ 0 ] = ' \0 ' ;
}
2002-11-18 17:04:08 +03:00
2012-02-10 05:28:27 +04:00
baton . dev = lvmcache_device ( info ) ;
2013-02-15 14:02:53 +04:00
baton . pvh_dlocn_xl = & pvhdr - > disk_areas_xl [ 0 ] ;
2002-11-18 17:04:08 +03:00
/* List of data areas (holding PEs) */
2012-02-10 05:28:27 +04:00
lvmcache_foreach_da ( info , _da_setup , & baton ) ;
2013-02-15 14:02:53 +04:00
_dl_null_termination ( & baton ) ;
2002-11-18 17:04:08 +03:00
/* List of metadata area header locations */
2012-02-10 05:28:27 +04:00
lvmcache_foreach_mda ( info , _mda_setup , & baton ) ;
2013-02-15 14:02:53 +04:00
_dl_null_termination ( & baton ) ;
/*
* PV header extension
*/
pvhdr_ext = ( struct pv_header_extension * ) ( ( char * ) baton . pvh_dlocn_xl ) ;
pvhdr_ext - > version = xlate32 ( PV_HEADER_EXTENSION_VSN ) ;
2015-03-09 14:52:07 +03:00
pvhdr_ext - > flags = xlate32 ( lvmcache_ext_flags ( info ) ) ;
2002-11-18 17:04:08 +03:00
2013-05-28 14:37:22 +04:00
/* List of bootloader area locations */
baton . pvh_dlocn_xl = & pvhdr_ext - > bootloader_areas_xl [ 0 ] ;
lvmcache_foreach_ba ( info , _ba_setup , & baton ) ;
2013-02-15 14:02:53 +04:00
_dl_null_termination ( & baton ) ;
2002-11-18 17:04:08 +03:00
2013-05-28 14:37:22 +04:00
/* Create debug message with ba, da and mda locations */
ba1 = ( xlate64 ( pvhdr_ext - > bootloader_areas_xl [ 0 ] . offset ) | |
xlate64 ( pvhdr_ext - > bootloader_areas_xl [ 0 ] . size ) ) ? 0 : - 1 ;
2013-02-15 14:02:53 +04:00
da1 = ( xlate64 ( pvhdr - > disk_areas_xl [ 0 ] . offset ) | |
xlate64 ( pvhdr - > disk_areas_xl [ 0 ] . size ) ) ? 0 : - 1 ;
2009-02-21 02:19:28 +03:00
mda1 = da1 + 2 ;
mda2 = mda1 + 1 ;
if ( ! xlate64 ( pvhdr - > disk_areas_xl [ mda1 ] . offset ) & &
! xlate64 ( pvhdr - > disk_areas_xl [ mda1 ] . size ) )
mda1 = mda2 = 0 ;
else if ( ! xlate64 ( pvhdr - > disk_areas_xl [ mda2 ] . offset ) & &
! xlate64 ( pvhdr - > disk_areas_xl [ mda2 ] . size ) )
mda2 = 0 ;
2017-12-11 18:32:53 +03:00
log_debug_metadata ( " %s: Preparing PV label header %s size " FMTu64 " with "
2013-02-15 14:02:53 +04:00
" %s%.* " PRIu64 " %s%.* " PRIu64 " %s "
2013-01-08 02:30:29 +04:00
" %s%.* " PRIu64 " %s%.* " PRIu64 " %s "
" %s%.* " PRIu64 " %s%.* " PRIu64 " %s "
" %s%.* " PRIu64 " %s%.* " PRIu64 " %s " ,
dev_name ( lvmcache_device ( info ) ) , buffer , lvmcache_device_size ( info ) ,
2013-05-28 14:37:22 +04:00
( ba1 > - 1 ) ? " ba1 ( " : " " ,
( ba1 > - 1 ) ? 1 : 0 ,
( ba1 > - 1 ) ? xlate64 ( pvhdr_ext - > bootloader_areas_xl [ ba1 ] . offset ) > > SECTOR_SHIFT : 0 ,
( ba1 > - 1 ) ? " s, " : " " ,
( ba1 > - 1 ) ? 1 : 0 ,
( ba1 > - 1 ) ? xlate64 ( pvhdr_ext - > bootloader_areas_xl [ ba1 ] . size ) > > SECTOR_SHIFT : 0 ,
( ba1 > - 1 ) ? " s) " : " " ,
2013-01-08 02:30:29 +04:00
( da1 > - 1 ) ? " da1 ( " : " " ,
( da1 > - 1 ) ? 1 : 0 ,
( da1 > - 1 ) ? xlate64 ( pvhdr - > disk_areas_xl [ da1 ] . offset ) > > SECTOR_SHIFT : 0 ,
( da1 > - 1 ) ? " s, " : " " ,
( da1 > - 1 ) ? 1 : 0 ,
( da1 > - 1 ) ? xlate64 ( pvhdr - > disk_areas_xl [ da1 ] . size ) > > SECTOR_SHIFT : 0 ,
( da1 > - 1 ) ? " s) " : " " ,
mda1 ? " mda1 ( " : " " ,
mda1 ? 1 : 0 ,
mda1 ? xlate64 ( pvhdr - > disk_areas_xl [ mda1 ] . offset ) > > SECTOR_SHIFT : 0 ,
mda1 ? " s, " : " " ,
mda1 ? 1 : 0 ,
mda1 ? xlate64 ( pvhdr - > disk_areas_xl [ mda1 ] . size ) > > SECTOR_SHIFT : 0 ,
mda1 ? " s) " : " " ,
mda2 ? " mda2 ( " : " " ,
mda2 ? 1 : 0 ,
mda2 ? xlate64 ( pvhdr - > disk_areas_xl [ mda2 ] . offset ) > > SECTOR_SHIFT : 0 ,
mda2 ? " s, " : " " ,
mda2 ? 1 : 0 ,
mda2 ? xlate64 ( pvhdr - > disk_areas_xl [ mda2 ] . size ) > > SECTOR_SHIFT : 0 ,
mda2 ? " s) " : " " ) ;
2009-02-21 02:19:28 +03:00
2009-02-22 22:00:26 +03:00
if ( da1 < 0 ) {
2009-12-16 22:22:11 +03:00
log_error ( INTERNAL_ERROR " %s label header currently requires "
2012-02-10 05:28:27 +04:00
" a data area. " , dev_name ( lvmcache_device ( info ) ) ) ;
2009-02-22 22:00:26 +03:00
return 0 ;
}
2002-11-18 17:04:08 +03:00
return 1 ;
}
2008-11-04 01:14:30 +03:00
int add_da ( struct dm_pool * mem , struct dm_list * das ,
2002-11-18 17:04:08 +03:00
uint64_t start , uint64_t size )
{
struct data_area_list * dal ;
if ( ! mem ) {
2005-10-17 03:03:59 +04:00
if ( ! ( dal = dm_malloc ( sizeof ( * dal ) ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " struct data_area_list allocation failed " ) ;
return 0 ;
}
} else {
2005-10-17 03:03:59 +04:00
if ( ! ( dal = dm_pool_alloc ( mem , sizeof ( * dal ) ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " struct data_area_list allocation failed " ) ;
return 0 ;
}
}
dal - > disk_locn . offset = start ;
dal - > disk_locn . size = size ;
2008-11-04 01:14:30 +03:00
dm_list_add ( das , & dal - > list ) ;
2002-11-18 17:04:08 +03:00
return 1 ;
}
2008-11-04 01:14:30 +03:00
void del_das ( struct dm_list * das )
2002-11-18 17:04:08 +03:00
{
2008-11-04 01:14:30 +03:00
struct dm_list * dah , * tmp ;
2002-11-18 17:04:08 +03:00
struct data_area_list * da ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_safe ( dah , tmp , das ) {
da = dm_list_item ( dah , struct data_area_list ) ;
dm_list_del ( & da - > list ) ;
2005-10-17 03:03:59 +04:00
dm_free ( da ) ;
2002-11-18 17:04:08 +03:00
}
}
2013-05-28 14:37:22 +04:00
int add_ba ( struct dm_pool * mem , struct dm_list * eas ,
2013-02-14 18:35:57 +04:00
uint64_t start , uint64_t size )
{
return add_da ( mem , eas , start , size ) ;
}
2013-05-28 14:37:22 +04:00
void del_bas ( struct dm_list * bas )
2013-02-14 18:35:57 +04:00
{
2013-05-28 14:37:22 +04:00
del_das ( bas ) ;
2013-02-14 18:35:57 +04:00
}
2010-06-30 16:17:24 +04:00
/* FIXME: refactor this function with other mda constructor code */
2008-11-04 01:14:30 +03:00
int add_mda ( const struct format_type * fmt , struct dm_pool * mem , struct dm_list * mdas ,
2010-06-30 16:17:24 +04:00
struct device * dev , uint64_t start , uint64_t size , unsigned ignored )
2002-11-18 17:04:08 +03:00
{
/* FIXME List size restricted by pv_header SECTOR_SIZE */
2017-12-07 06:34:59 +03:00
struct metadata_area * mdal , * mda ;
2002-11-18 17:04:08 +03:00
struct mda_lists * mda_lists = ( struct mda_lists * ) fmt - > private ;
2017-12-07 06:34:59 +03:00
struct mda_context * mdac , * mdac2 ;
2002-11-18 17:04:08 +03:00
if ( ! mem ) {
2005-10-17 03:03:59 +04:00
if ( ! ( mdal = dm_malloc ( sizeof ( struct metadata_area ) ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " struct mda_list allocation failed " ) ;
return 0 ;
}
2005-10-17 03:03:59 +04:00
if ( ! ( mdac = dm_malloc ( sizeof ( struct mda_context ) ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " struct mda_context allocation failed " ) ;
2005-10-17 03:03:59 +04:00
dm_free ( mdal ) ;
2002-11-18 17:04:08 +03:00
return 0 ;
}
} else {
2005-10-17 03:03:59 +04:00
if ( ! ( mdal = dm_pool_alloc ( mem , sizeof ( struct metadata_area ) ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " struct mda_list allocation failed " ) ;
return 0 ;
}
2005-10-17 03:03:59 +04:00
if ( ! ( mdac = dm_pool_alloc ( mem , sizeof ( struct mda_context ) ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " struct mda_context allocation failed " ) ;
return 0 ;
}
}
mdal - > ops = mda_lists - > raw_ops ;
mdal - > metadata_locn = mdac ;
mdac - > area . dev = dev ;
mdac - > area . start = start ;
mdac - > area . size = size ;
2007-11-05 20:17:55 +03:00
mdac - > free_sectors = UINT64_C ( 0 ) ;
2002-11-18 17:04:08 +03:00
memset ( & mdac - > rlocn , 0 , sizeof ( mdac - > rlocn ) ) ;
2017-12-07 06:34:59 +03:00
/* Set MDA_PRIMARY only if this is the first metadata area on this device. */
mdal - > status = MDA_PRIMARY ;
dm_list_iterate_items ( mda , mdas ) {
mdac2 = mda - > metadata_locn ;
if ( mdac2 - > area . dev = = dev ) {
mdal - > status = 0 ;
break ;
}
}
2010-06-30 16:17:24 +04:00
mda_set_ignored ( mdal , ignored ) ;
2002-11-18 17:04:08 +03:00
2008-11-04 01:14:30 +03:00
dm_list_add ( mdas , & mdal - > list ) ;
2002-11-18 17:04:08 +03:00
return 1 ;
}
2008-11-04 01:14:30 +03:00
void del_mdas ( struct dm_list * mdas )
2002-11-18 17:04:08 +03:00
{
2008-11-04 01:14:30 +03:00
struct dm_list * mdah , * tmp ;
2002-11-18 17:04:08 +03:00
struct metadata_area * mda ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_safe ( mdah , tmp , mdas ) {
mda = dm_list_item ( mdah , struct metadata_area ) ;
2005-10-17 03:03:59 +04:00
dm_free ( mda - > metadata_locn ) ;
2008-11-04 01:14:30 +03:00
dm_list_del ( & mda - > list ) ;
2005-10-17 03:03:59 +04:00
dm_free ( mda ) ;
2002-11-18 17:04:08 +03:00
}
}
2010-07-09 19:34:40 +04:00
static int _text_initialise_label ( struct labeller * l __attribute__ ( ( unused ) ) ,
2006-05-11 21:58:58 +04:00
struct label * label )
2002-11-18 17:04:08 +03:00
{
strncpy ( label - > type , LVM2_LABEL , sizeof ( label - > type ) ) ;
return 1 ;
}
2018-01-04 02:53:00 +03:00
struct update_mda_baton {
2012-02-10 05:28:27 +04:00
struct lvmcache_info * info ;
2018-01-15 23:13:53 +03:00
struct label * label ;
2018-01-07 06:43:25 +03:00
int nr_outstanding_mdas ;
2018-01-21 18:41:49 +03:00
unsigned ioflags ;
2018-01-07 06:43:25 +03:00
lvm_callback_fn_t read_label_callback_fn ;
void * read_label_callback_context ;
2018-01-04 02:53:00 +03:00
int ret ;
2012-02-10 05:28:27 +04:00
} ;
2018-01-04 03:56:34 +03:00
struct process_mda_header_params {
struct update_mda_baton * umb ;
struct metadata_area * mda ;
struct device * dev ;
struct lvmcache_vgsummary vgsummary ;
2018-01-05 05:31:28 +03:00
int ret ;
2018-01-04 03:56:34 +03:00
} ;
2018-01-21 18:41:49 +03:00
static void _process_vgsummary ( int failed , unsigned ioflags , void * context , const void * data )
2018-01-04 03:56:34 +03:00
{
2018-01-05 17:24:10 +03:00
struct process_mda_header_params * pmp = context ;
2018-01-10 22:50:53 +03:00
const struct lvmcache_vgsummary * vgsummary = data ;
2018-01-05 17:24:10 +03:00
2018-01-07 06:43:25 +03:00
- - pmp - > umb - > nr_outstanding_mdas ;
2018-02-07 00:43:06 +03:00
/* FIXME Need to distinguish genuine errors here */
2018-01-09 04:50:23 +03:00
if ( failed )
goto_out ;
2018-01-04 03:56:34 +03:00
if ( ! lvmcache_update_vgname_and_id ( pmp - > umb - > info , vgsummary ) ) {
pmp - > umb - > ret = 0 ;
2018-01-05 05:31:28 +03:00
pmp - > ret = 0 ;
2018-01-04 03:56:34 +03:00
}
out :
2018-01-15 23:43:51 +03:00
if ( ! pmp - > umb - > nr_outstanding_mdas & & pmp - > umb - > ret )
lvmcache_make_valid ( pmp - > umb - > info ) ;
2018-01-04 03:56:34 +03:00
if ( ! dev_close ( pmp - > dev ) )
stack ;
2018-01-15 23:43:51 +03:00
if ( ! pmp - > umb - > nr_outstanding_mdas & & pmp - > umb - > read_label_callback_fn )
2018-01-21 18:41:49 +03:00
pmp - > umb - > read_label_callback_fn ( ! pmp - > umb - > ret , ioflags , pmp - > umb - > read_label_callback_context , pmp - > umb - > label ) ;
2018-01-04 03:56:34 +03:00
}
2018-01-21 18:41:49 +03:00
static void _process_mda_header ( int failed , unsigned ioflags , void * context , const void * data )
2018-01-04 03:56:34 +03:00
{
2018-01-05 17:24:10 +03:00
struct process_mda_header_params * pmp = context ;
2018-01-10 22:50:53 +03:00
const struct mda_header * mdah = data ;
2018-01-04 03:56:34 +03:00
struct update_mda_baton * umb = pmp - > umb ;
2018-01-15 23:13:53 +03:00
const struct format_type * fmt = umb - > label - > labeller - > fmt ;
2018-01-04 03:56:34 +03:00
struct metadata_area * mda = pmp - > mda ;
struct mda_context * mdac = ( struct mda_context * ) mda - > metadata_locn ;
2018-01-07 06:43:25 +03:00
if ( failed )
2018-01-15 23:43:51 +03:00
goto_bad ;
2018-01-07 06:43:25 +03:00
2018-01-04 03:56:34 +03:00
mda_set_ignored ( mda , rlocn_is_ignored ( mdah - > raw_locns ) ) ;
if ( mda_is_ignored ( mda ) ) {
log_debug_metadata ( " Ignoring mda on device %s at offset " FMTu64 ,
dev_name ( mdac - > area . dev ) ,
mdac - > area . start ) ;
2018-01-09 04:50:23 +03:00
goto bad ;
2018-01-04 03:56:34 +03:00
}
2018-01-21 18:41:49 +03:00
if ( ! vgname_from_mda ( fmt , mdah , mda_is_primary ( mda ) , & mdac - > area , & pmp - > vgsummary , & mdac - > free_sectors , ioflags , _process_vgsummary , pmp ) ) {
2018-01-04 03:56:34 +03:00
/* FIXME Separate fatal and non-fatal error cases? */
2018-01-09 04:50:23 +03:00
goto_bad ;
2018-01-04 03:56:34 +03:00
}
2018-01-09 04:50:23 +03:00
return ;
bad :
2018-01-21 18:41:49 +03:00
_process_vgsummary ( 1 , ioflags , pmp , NULL ) ;
2018-01-09 04:50:23 +03:00
return ;
2018-01-04 03:56:34 +03:00
}
2018-01-15 23:43:51 +03:00
static int _count_mda ( struct metadata_area * mda , void * baton )
{
struct update_mda_baton * umb = baton ;
umb - > nr_outstanding_mdas + + ;
return 1 ;
}
2012-02-10 05:28:27 +04:00
static int _update_mda ( struct metadata_area * mda , void * baton )
{
2018-01-04 03:56:34 +03:00
struct process_mda_header_params * pmp ;
2018-01-04 02:53:00 +03:00
struct update_mda_baton * umb = baton ;
2018-01-15 23:13:53 +03:00
const struct format_type * fmt = umb - > label - > labeller - > fmt ;
struct dm_pool * mem = umb - > label - > labeller - > fmt - > cmd - > mem ;
2012-02-10 05:28:27 +04:00
struct mda_context * mdac = ( struct mda_context * ) mda - > metadata_locn ;
2018-01-21 18:41:49 +03:00
unsigned ioflags = umb - > ioflags ;
2018-01-04 03:56:34 +03:00
if ( ! ( pmp = dm_pool_zalloc ( mem , sizeof ( * pmp ) ) ) ) {
log_error ( " struct process_mda_header_params allocation failed " ) ;
return 0 ;
}
2015-03-06 12:24:26 +03:00
/*
* Using the labeller struct to preserve info about
* the last parsed vgname , vgid , creation host
*
* TODO : make lvmcache smarter and move this cache logic there
*/
2012-02-10 05:28:27 +04:00
2018-01-15 23:43:51 +03:00
pmp - > dev = mdac - > area . dev ;
pmp - > umb = umb ;
pmp - > mda = mda ;
2012-02-10 05:28:27 +04:00
if ( ! dev_open_readonly ( mdac - > area . dev ) ) {
mda_set_ignored ( mda , 1 ) ;
stack ;
2018-01-15 23:43:51 +03:00
if ( ! - - umb - > nr_outstanding_mdas & & umb - > read_label_callback_fn )
2018-01-21 18:41:49 +03:00
umb - > read_label_callback_fn ( ! umb - > ret , ioflags , umb - > read_label_callback_context , umb - > label ) ;
2012-02-10 05:28:27 +04:00
return 1 ;
}
2018-01-05 05:31:28 +03:00
pmp - > ret = 1 ;
2012-02-10 05:28:27 +04:00
2018-01-21 18:41:49 +03:00
if ( ! raw_read_mda_header_callback ( fmt - > cmd - > mem , & mdac - > area , mda_is_primary ( mda ) , ioflags , _process_mda_header , pmp ) ) {
_process_vgsummary ( 1 , ioflags , pmp , NULL ) ;
2018-01-04 02:53:00 +03:00
stack ;
2018-01-04 03:56:34 +03:00
return 1 ;
2012-02-10 05:28:27 +04:00
}
2015-03-06 12:24:26 +03:00
2018-02-07 00:43:06 +03:00
if ( umb - > read_label_callback_fn )
return 1 ;
else
return pmp - > ret ;
2012-02-10 05:28:27 +04:00
}
2018-01-21 18:41:49 +03:00
static int _text_read ( struct labeller * l , struct device * dev , void * buf , unsigned ioflags ,
2018-01-07 06:43:25 +03:00
lvm_callback_fn_t read_label_callback_fn , void * read_label_callback_context )
2002-11-18 17:04:08 +03:00
{
struct label_header * lh = ( struct label_header * ) buf ;
struct pv_header * pvhdr ;
2013-02-14 19:04:35 +04:00
struct pv_header_extension * pvhdr_ext ;
2003-07-05 02:34:56 +04:00
struct lvmcache_info * info ;
2002-11-18 17:04:08 +03:00
struct disk_locn * dlocn_xl ;
uint64_t offset ;
2013-02-14 19:04:35 +04:00
uint32_t ext_version ;
2018-01-04 02:53:00 +03:00
struct dm_pool * mem = l - > fmt - > cmd - > mem ;
struct update_mda_baton * umb ;
2018-01-15 23:43:51 +03:00
struct label * label ;
2002-11-18 17:04:08 +03:00
2013-02-14 19:04:35 +04:00
/*
* PV header base
*/
2011-02-18 17:34:41 +03:00
pvhdr = ( struct pv_header * ) ( ( char * ) buf + xlate32 ( lh - > offset_xl ) ) ;
2002-11-18 17:04:08 +03:00
2008-02-06 18:47:28 +03:00
if ( ! ( info = lvmcache_add ( l , ( char * ) pvhdr - > pv_uuid , dev ,
FMT_TEXT_ORPHAN_VG_NAME ,
FMT_TEXT_ORPHAN_VG_NAME , 0 ) ) )
2018-01-04 02:53:00 +03:00
goto_bad ;
2002-11-18 17:04:08 +03:00
2018-01-11 05:39:30 +03:00
label = lvmcache_get_label ( info ) ;
2002-11-18 17:04:08 +03:00
2012-02-10 05:28:27 +04:00
lvmcache_set_device_size ( info , xlate64 ( pvhdr - > device_size_xl ) ) ;
2002-11-18 17:04:08 +03:00
2012-02-10 05:28:27 +04:00
lvmcache_del_das ( info ) ;
lvmcache_del_mdas ( info ) ;
2013-05-28 14:37:22 +04:00
lvmcache_del_bas ( info ) ;
2002-11-18 17:04:08 +03:00
/* Data areas holding the PEs */
dlocn_xl = pvhdr - > disk_areas_xl ;
while ( ( offset = xlate64 ( dlocn_xl - > offset ) ) ) {
2012-02-10 05:28:27 +04:00
lvmcache_add_da ( info , offset , xlate64 ( dlocn_xl - > size ) ) ;
2002-11-18 17:04:08 +03:00
dlocn_xl + + ;
}
/* Metadata area headers */
dlocn_xl + + ;
while ( ( offset = xlate64 ( dlocn_xl - > offset ) ) ) {
2012-02-10 05:28:27 +04:00
lvmcache_add_mda ( info , dev , offset , xlate64 ( dlocn_xl - > size ) , 0 ) ;
2002-11-18 17:04:08 +03:00
dlocn_xl + + ;
}
2013-02-14 19:04:35 +04:00
dlocn_xl + + ;
/*
* PV header extension
*/
pvhdr_ext = ( struct pv_header_extension * ) ( ( char * ) dlocn_xl ) ;
if ( ! ( ext_version = xlate32 ( pvhdr_ext - > version ) ) )
goto out ;
2017-12-11 18:32:53 +03:00
log_debug_metadata ( " %s: PV header extension version " FMTu32 " found " ,
2015-05-11 12:07:53 +03:00
dev_name ( dev ) , ext_version ) ;
2013-02-14 19:04:35 +04:00
2016-02-11 18:25:36 +03:00
/* Extension version */
lvmcache_set_ext_version ( info , xlate32 ( pvhdr_ext - > version ) ) ;
2015-03-09 14:52:07 +03:00
/* Extension flags */
lvmcache_set_ext_flags ( info , xlate32 ( pvhdr_ext - > flags ) ) ;
2013-05-28 14:37:22 +04:00
/* Bootloader areas */
dlocn_xl = pvhdr_ext - > bootloader_areas_xl ;
2013-02-14 19:04:35 +04:00
while ( ( offset = xlate64 ( dlocn_xl - > offset ) ) ) {
2013-05-28 14:37:22 +04:00
lvmcache_add_ba ( info , offset , xlate64 ( dlocn_xl - > size ) ) ;
2013-02-14 19:04:35 +04:00
dlocn_xl + + ;
}
2018-01-04 02:53:00 +03:00
2013-02-14 19:04:35 +04:00
out :
2018-01-04 02:53:00 +03:00
if ( ! ( umb = dm_pool_zalloc ( mem , sizeof ( * umb ) ) ) ) {
log_error ( " baton allocation failed " ) ;
goto_bad ;
}
umb - > info = info ;
2018-01-15 23:13:53 +03:00
umb - > label = label ;
2018-01-21 18:41:49 +03:00
umb - > ioflags = ioflags ;
2018-01-07 06:43:25 +03:00
umb - > read_label_callback_fn = read_label_callback_fn ;
umb - > read_label_callback_context = read_label_callback_context ;
2018-01-04 02:53:00 +03:00
umb - > ret = 1 ;
2002-11-18 17:04:08 +03:00
2018-01-15 23:43:51 +03:00
if ( ! lvmcache_foreach_mda ( info , _count_mda , umb ) )
goto_bad ;
2017-08-16 15:29:12 +03:00
2018-01-15 23:43:51 +03:00
if ( ! umb - > nr_outstanding_mdas ) {
lvmcache_make_valid ( info ) ;
if ( read_label_callback_fn )
2018-01-21 18:41:49 +03:00
read_label_callback_fn ( 0 , ioflags , read_label_callback_context , label ) ;
2018-01-15 23:43:51 +03:00
return 1 ;
}
2018-01-07 06:43:25 +03:00
2018-01-15 23:43:51 +03:00
if ( ! lvmcache_foreach_mda ( info , _update_mda , umb ) )
goto_bad ;
2002-11-18 17:04:08 +03:00
return 1 ;
2018-01-04 02:53:00 +03:00
bad :
2018-01-07 06:43:25 +03:00
if ( read_label_callback_fn )
2018-01-22 18:41:11 +03:00
read_label_callback_fn ( 1 , ioflags , read_label_callback_context , NULL ) ;
2018-01-07 06:43:25 +03:00
2018-01-04 02:53:00 +03:00
return 0 ;
2002-11-18 17:04:08 +03:00
}
2010-07-09 19:34:40 +04:00
static void _text_destroy_label ( struct labeller * l __attribute__ ( ( unused ) ) ,
2006-05-11 21:58:58 +04:00
struct label * label )
2002-11-18 17:04:08 +03:00
{
2003-07-05 02:34:56 +04:00
struct lvmcache_info * info = ( struct lvmcache_info * ) label - > info ;
2002-11-18 17:04:08 +03:00
2012-02-10 05:28:27 +04:00
lvmcache_del_mdas ( info ) ;
lvmcache_del_das ( info ) ;
2013-05-28 14:37:22 +04:00
lvmcache_del_bas ( info ) ;
2002-11-18 17:04:08 +03:00
}
2006-04-19 19:33:07 +04:00
static void _fmt_text_destroy ( struct labeller * l )
2002-11-18 17:04:08 +03:00
{
2005-10-17 03:03:59 +04:00
dm_free ( l ) ;
2002-11-18 17:04:08 +03:00
}
struct label_ops _text_ops = {
2006-05-10 01:23:51 +04:00
. can_handle = _text_can_handle ,
. write = _text_write ,
. read = _text_read ,
. initialise_label = _text_initialise_label ,
. destroy_label = _text_destroy_label ,
. destroy = _fmt_text_destroy ,
2002-11-18 17:04:08 +03:00
} ;
2002-12-20 02:25:55 +03:00
struct labeller * text_labeller_create ( const struct format_type * fmt )
2002-11-18 17:04:08 +03:00
{
struct labeller * l ;
2015-03-06 10:42:20 +03:00
if ( ! ( l = dm_zalloc ( sizeof ( * l ) ) ) ) {
2009-07-16 00:02:46 +04:00
log_error ( " Couldn't allocate labeller object. " ) ;
2002-11-18 17:04:08 +03:00
return NULL ;
}
l - > ops = & _text_ops ;
2013-07-29 17:58:18 +04:00
l - > fmt = fmt ;
2002-11-18 17:04:08 +03:00
return l ;
}