2004-06-07 23:10:21 +04:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 1997 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2004-06-07 23:10:21 +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-06-07 23:10:21 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-06-07 23:10:21 +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
*/
# include "lib.h"
# include "label.h"
# include "metadata.h"
# include "lvmcache.h"
# include "disk_rep.h"
2005-01-20 21:12:41 +03:00
# include "sptype_names.h"
2004-06-07 23:10:21 +04:00
# include "lv_alloc.h"
2005-04-20 00:58:25 +04:00
# include "pv_alloc.h"
2004-06-07 23:10:21 +04:00
# include "str_list.h"
# include "display.h"
2004-09-16 22:40:56 +04:00
# include "segtype.h"
2007-11-09 19:51:54 +03:00
# include "toolcontext.h"
2004-06-07 23:10:21 +04:00
/* This file contains only imports at the moment... */
2008-11-04 01:14:30 +03:00
int import_pool_vg ( struct volume_group * vg , struct dm_pool * mem , struct dm_list * pls )
2004-06-07 23:10:21 +04:00
{
struct pool_list * pl ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( pl , pls ) {
2004-06-07 23:10:21 +04:00
vg - > extent_count + =
( ( pl - > pd . pl_blocks ) / POOL_PE_SIZE ) ;
2008-06-10 18:55:14 +04:00
vg - > free_count = vg - > extent_count ;
2004-06-07 23:10:21 +04:00
vg - > pv_count + + ;
if ( vg - > name )
continue ;
2005-10-17 03:03:59 +04:00
vg - > name = dm_pool_strdup ( mem , pl - > pd . pl_pool_name ) ;
2004-06-07 23:10:21 +04:00
get_pool_vg_uuid ( & vg - > id , & pl - > pd ) ;
vg - > extent_size = POOL_PE_SIZE ;
vg - > status | = LVM_READ | LVM_WRITE | CLUSTERED | SHARED ;
vg - > max_lv = 1 ;
vg - > max_pv = POOL_MAX_DEVICES ;
vg - > alloc = ALLOC_NORMAL ;
}
return 1 ;
}
2008-11-04 01:14:30 +03:00
int import_pool_lvs ( struct volume_group * vg , struct dm_pool * mem , struct dm_list * pls )
2004-06-07 23:10:21 +04:00
{
struct pool_list * pl ;
struct logical_volume * lv ;
2009-05-14 01:25:01 +04:00
if ( ! ( lv = dm_pool_zalloc ( mem , sizeof ( * lv ) ) ) ) {
2004-06-07 23:10:21 +04:00
log_error ( " Unable to allocate logical volume structure " ) ;
return 0 ;
}
lv - > status = 0 ;
lv - > alloc = ALLOC_NORMAL ;
lv - > size = 0 ;
lv - > name = NULL ;
lv - > le_count = 0 ;
2007-11-09 19:51:54 +03:00
lv - > read_ahead = vg - > cmd - > default_settings . read_ahead ;
2005-04-07 16:39:44 +04:00
lv - > snapshot = NULL ;
2008-11-04 01:14:30 +03:00
dm_list_init ( & lv - > snapshot_segs ) ;
dm_list_init ( & lv - > segments ) ;
dm_list_init ( & lv - > tags ) ;
dm_list_init ( & lv - > segs_using_this_lv ) ;
2004-06-07 23:10:21 +04:00
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( pl , pls ) {
2004-06-07 23:10:21 +04:00
lv - > size + = pl - > pd . pl_blocks ;
if ( lv - > name )
continue ;
2008-01-30 16:19:47 +03:00
if ( ! ( lv - > name = dm_pool_strdup ( mem , pl - > pd . pl_pool_name ) ) )
return_0 ;
2004-06-07 23:10:21 +04:00
get_pool_lv_uuid ( lv - > lvid . id , & pl - > pd ) ;
log_debug ( " Calculated lv uuid for lv %s: %s " , lv - > name ,
lv - > lvid . s ) ;
lv - > status | = VISIBLE_LV | LVM_READ | LVM_WRITE ;
lv - > major = POOL_MAJOR ;
/* for pool a minor of 0 is dynamic */
if ( pl - > pd . pl_minor ) {
lv - > status | = FIXED_MINOR ;
2005-02-09 20:49:36 +03:00
lv - > minor = pl - > pd . pl_minor + MINOR_OFFSET ;
2004-06-07 23:10:21 +04:00
} else {
lv - > minor = - 1 ;
}
2005-04-07 16:39:44 +04:00
lv - > snapshot = NULL ;
2008-11-04 01:14:30 +03:00
dm_list_init ( & lv - > snapshot_segs ) ;
dm_list_init ( & lv - > segments ) ;
dm_list_init ( & lv - > tags ) ;
2004-06-07 23:10:21 +04:00
}
lv - > le_count = lv - > size / POOL_PE_SIZE ;
2009-05-14 01:25:01 +04:00
return link_lv_to_vg ( vg , lv ) ;
2004-06-07 23:10:21 +04:00
}
int import_pool_pvs ( const struct format_type * fmt , struct volume_group * vg ,
2008-11-04 01:14:30 +03:00
struct dm_list * pvs , struct dm_pool * mem , struct dm_list * pls )
2004-06-07 23:10:21 +04:00
{
struct pv_list * pvl ;
struct pool_list * pl ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( pl , pls ) {
2005-10-17 03:03:59 +04:00
if ( ! ( pvl = dm_pool_zalloc ( mem , sizeof ( * pvl ) ) ) ) {
2004-06-07 23:10:21 +04:00
log_error ( " Unable to allocate pv list structure " ) ;
return 0 ;
}
2005-10-17 03:03:59 +04:00
if ( ! ( pvl - > pv = dm_pool_zalloc ( mem , sizeof ( * pvl - > pv ) ) ) ) {
2004-06-07 23:10:21 +04:00
log_error ( " Unable to allocate pv structure " ) ;
return 0 ;
}
if ( ! import_pool_pv ( fmt , mem , vg , pvl - > pv , pl ) ) {
return 0 ;
}
pl - > pv = pvl - > pv ;
pvl - > mdas = NULL ;
2004-08-18 01:55:23 +04:00
pvl - > pe_ranges = NULL ;
2008-11-04 01:14:30 +03:00
dm_list_add ( pvs , & pvl - > list ) ;
2004-06-07 23:10:21 +04:00
}
return 1 ;
}
2005-10-17 03:03:59 +04:00
int import_pool_pv ( const struct format_type * fmt , struct dm_pool * mem ,
2004-06-07 23:10:21 +04:00
struct volume_group * vg , struct physical_volume * pv ,
struct pool_list * pl )
{
struct pool_disk * pd = & pl - > pd ;
memset ( pv , 0 , sizeof ( * pv ) ) ;
get_pool_pv_uuid ( & pv - > id , pd ) ;
pv - > fmt = fmt ;
pv - > dev = pl - > dev ;
2005-10-17 03:03:59 +04:00
if ( ! ( pv - > vg_name = dm_pool_strdup ( mem , pd - > pl_pool_name ) ) ) {
2004-06-07 23:10:21 +04:00
log_error ( " Unable to duplicate vg_name string " ) ;
return 0 ;
}
2008-06-11 17:14:41 +04:00
if ( vg ! = NULL )
memcpy ( & pv - > vgid , & vg - > id , sizeof ( vg - > id ) ) ;
2004-06-07 23:10:21 +04:00
pv - > status = 0 ;
pv - > size = pd - > pl_blocks ;
pv - > pe_size = POOL_PE_SIZE ;
pv - > pe_start = POOL_PE_START ;
pv - > pe_count = pv - > size / POOL_PE_SIZE ;
2005-06-01 20:51:55 +04:00
pv - > pe_alloc_count = 0 ;
2008-09-19 08:28:58 +04:00
pv - > pe_align = 0 ;
2004-06-07 23:10:21 +04:00
2008-11-04 01:14:30 +03:00
dm_list_init ( & pv - > tags ) ;
dm_list_init ( & pv - > segments ) ;
2005-04-20 00:58:25 +04:00
2008-01-30 16:19:47 +03:00
if ( ! alloc_pv_segment_whole_pv ( mem , pv ) )
return_0 ;
2004-06-07 23:10:21 +04:00
return 1 ;
}
static const char * _cvt_sptype ( uint32_t sptype )
{
int i ;
for ( i = 0 ; sptype_names [ i ] . name [ 0 ] ; i + + ) {
if ( sptype = = sptype_names [ i ] . label ) {
break ;
}
}
log_debug ( " Found sptype %X and converted it to %s " ,
sptype , sptype_names [ i ] . name ) ;
return sptype_names [ i ] . name ;
}
2005-10-17 03:03:59 +04:00
static int _add_stripe_seg ( struct dm_pool * mem ,
2004-06-07 23:10:21 +04:00
struct user_subpool * usp , struct logical_volume * lv ,
uint32_t * le_cur )
{
struct lv_segment * seg ;
2005-04-22 19:44:00 +04:00
struct segment_type * segtype ;
2006-05-10 01:23:51 +04:00
unsigned j ;
2005-04-22 19:44:00 +04:00
uint32_t area_len ;
2004-06-07 23:10:21 +04:00
2005-04-22 19:43:02 +04:00
if ( usp - > striping & ( usp - > striping - 1 ) ) {
2004-06-07 23:10:21 +04:00
log_error ( " Stripe size must be a power of 2 " ) ;
return 0 ;
}
2005-04-22 19:44:00 +04:00
area_len = ( usp - > devs [ 0 ] . blocks ) / POOL_PE_SIZE ;
2004-06-07 23:10:21 +04:00
2005-04-22 19:44:00 +04:00
if ( ! ( segtype = get_segtype_from_string ( lv - > vg - > cmd ,
2008-01-30 16:19:47 +03:00
" striped " ) ) )
return_0 ;
2004-06-07 23:10:21 +04:00
2008-01-30 17:00:02 +03:00
if ( ! ( seg = alloc_lv_segment ( mem , segtype , lv , * le_cur ,
2005-04-22 19:44:00 +04:00
area_len * usp - > num_devs , 0 ,
2005-06-01 20:51:55 +04:00
usp - > striping , NULL , usp - > num_devs ,
area_len , 0 , 0 , 0 ) ) ) {
2005-04-22 19:44:00 +04:00
log_error ( " Unable to allocate striped lv_segment structure " ) ;
return 0 ;
}
2004-06-07 23:10:21 +04:00
2005-04-22 19:44:00 +04:00
for ( j = 0 ; j < usp - > num_devs ; j + + )
2008-01-30 16:19:47 +03:00
if ( ! set_lv_segment_area_pv ( seg , j , usp - > devs [ j ] . pv , 0 ) )
return_0 ;
2005-04-22 19:44:00 +04:00
/* add the subpool type to the segment tag list */
str_list_add ( mem , & seg - > tags , _cvt_sptype ( usp - > type ) ) ;
2005-04-22 19:43:02 +04:00
2008-11-04 01:14:30 +03:00
dm_list_add ( & lv - > segments , & seg - > list ) ;
2005-04-22 19:43:02 +04:00
2005-04-22 19:44:00 +04:00
* le_cur + = seg - > len ;
2004-06-07 23:10:21 +04:00
return 1 ;
}
2005-10-17 03:03:59 +04:00
static int _add_linear_seg ( struct dm_pool * mem ,
2004-06-07 23:10:21 +04:00
struct user_subpool * usp , struct logical_volume * lv ,
uint32_t * le_cur )
{
struct lv_segment * seg ;
2005-04-22 19:44:00 +04:00
struct segment_type * segtype ;
2006-05-10 01:23:51 +04:00
unsigned j ;
2005-04-22 19:44:00 +04:00
uint32_t area_len ;
2008-01-30 16:19:47 +03:00
if ( ! ( segtype = get_segtype_from_string ( lv - > vg - > cmd , " striped " ) ) )
return_0 ;
2004-06-07 23:10:21 +04:00
for ( j = 0 ; j < usp - > num_devs ; j + + ) {
2005-04-22 19:44:00 +04:00
area_len = ( usp - > devs [ j ] . blocks ) / POOL_PE_SIZE ;
if ( ! ( seg = alloc_lv_segment ( mem , segtype , lv , * le_cur ,
area_len , 0 , usp - > striping ,
2005-06-01 20:51:55 +04:00
NULL , 1 , area_len ,
POOL_PE_SIZE , 0 , 0 ) ) ) {
2004-06-07 23:10:21 +04:00
log_error ( " Unable to allocate linear lv_segment "
" structure " ) ;
return 0 ;
}
2005-04-22 19:44:00 +04:00
2004-06-07 23:10:21 +04:00
/* add the subpool type to the segment tag list */
str_list_add ( mem , & seg - > tags , _cvt_sptype ( usp - > type ) ) ;
2008-01-30 16:19:47 +03:00
if ( ! set_lv_segment_area_pv ( seg , 0 , usp - > devs [ j ] . pv , 0 ) )
return_0 ;
2008-11-04 01:14:30 +03:00
dm_list_add ( & lv - > segments , & seg - > list ) ;
2005-04-22 19:44:00 +04:00
* le_cur + = seg - > len ;
2004-06-07 23:10:21 +04:00
}
2005-04-22 19:44:00 +04:00
2004-06-07 23:10:21 +04:00
return 1 ;
}
2008-11-04 01:14:30 +03:00
int import_pool_segments ( struct dm_list * lvs , struct dm_pool * mem ,
2004-06-07 23:10:21 +04:00
struct user_subpool * usp , int subpools )
{
struct lv_list * lvl ;
struct logical_volume * lv ;
uint32_t le_cur = 0 ;
int i ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( lvl , lvs ) {
2004-06-07 23:10:21 +04:00
lv = lvl - > lv ;
2005-04-07 16:39:44 +04:00
if ( lv - > status & SNAPSHOT )
continue ;
2004-06-07 23:10:21 +04:00
for ( i = 0 ; i < subpools ; i + + ) {
if ( usp [ i ] . striping ) {
2008-01-30 16:19:47 +03:00
if ( ! _add_stripe_seg ( mem , & usp [ i ] , lv , & le_cur ) )
return_0 ;
2004-06-07 23:10:21 +04:00
} else {
2008-01-30 16:19:47 +03:00
if ( ! _add_linear_seg ( mem , & usp [ i ] , lv , & le_cur ) )
return_0 ;
2004-06-07 23:10:21 +04:00
}
}
}
return 1 ;
}