2001-10-04 21:48:55 +04:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
2001-10-31 15:47:01 +03:00
* This file is released under the LGPL .
2001-10-04 21:48:55 +04:00
*/
# include "disk-rep.h"
# include "dbg_malloc.h"
# include "pool.h"
# include "hash.h"
2002-02-14 00:28:56 +03:00
# include "limits.h"
2001-10-04 21:48:55 +04:00
# include "list.h"
2001-10-08 13:45:16 +04:00
# include "log.h"
2001-10-16 00:29:15 +04:00
# include "display.h"
2002-02-11 23:50:53 +03:00
# include "toolcontext.h"
2001-10-04 21:48:55 +04:00
2001-10-16 20:25:28 +04:00
/* VG consistency checks */
2002-01-29 20:23:33 +03:00
static int _check_vgs ( struct list * pvs , int * partial )
2001-10-04 21:48:55 +04:00
{
2002-01-29 20:23:33 +03:00
struct list * pvh , * t ;
2001-10-25 17:08:29 +04:00
struct disk_list * dl = NULL ;
2001-10-16 20:25:28 +04:00
struct disk_list * first = NULL ;
int pv_count = 0 ;
2002-01-29 20:23:33 +03:00
int exported = - 1 ;
* partial = 0 ;
2001-10-04 21:48:55 +04:00
2002-01-29 20:23:33 +03:00
/*
* If there are exported and unexported PVs , ignore exported ones .
* This means an active VG won ' t be affected if disks are inserted
* bearing an exported VG with the same name .
2002-02-12 19:31:31 +03:00
*/
2001-10-31 15:47:01 +03:00
list_iterate ( pvh , pvs ) {
dl = list_item ( pvh , struct disk_list ) ;
2001-10-04 21:48:55 +04:00
2002-01-29 20:23:33 +03:00
if ( exported < 0 ) {
exported = dl - > pvd . pv_status & VG_EXPORTED ;
continue ;
}
if ( exported ! = ( dl - > pvd . pv_status & VG_EXPORTED ) ) {
/* Remove exported PVs */
list_iterate_safe ( pvh , t , pvs ) {
dl = list_item ( pvh , struct disk_list ) ;
if ( dl - > pvd . pv_status & VG_EXPORTED )
list_del ( pvh ) ;
}
break ;
}
}
/* Remove any PVs with VG structs that differ from the first */
list_iterate_safe ( pvh , t , pvs ) {
dl = list_item ( pvh , struct disk_list ) ;
2001-10-09 18:26:45 +04:00
if ( ! first )
2001-10-16 20:25:28 +04:00
first = dl ;
2001-11-12 15:16:57 +03:00
2001-10-31 20:59:52 +03:00
else if ( memcmp ( & first - > vgd , & dl - > vgd , sizeof ( first - > vgd ) ) ) {
2002-01-28 00:30:47 +03:00
log_error ( " VG data differs between PVs %s and %s " ,
dev_name ( first - > dev ) , dev_name ( dl - > dev ) ) ;
2002-01-29 20:23:33 +03:00
list_del ( pvh ) ;
if ( partial_mode ( ) ) {
* partial = 1 ;
continue ;
}
2001-10-04 21:48:55 +04:00
return 0 ;
}
2001-10-16 20:25:28 +04:00
pv_count + + ;
}
/* On entry to fn, list known to be non-empty */
2002-01-29 20:23:33 +03:00
if ( pv_count ! = dl - > vgd . pv_cur ) {
log_error ( " %d PV(s) found for VG %s: expected %d " ,
pv_count , dl - > pvd . vg_name , dl - > vgd . pv_cur ) ;
if ( ! partial_mode ( ) )
return 0 ;
* partial = 1 ;
2001-10-04 21:48:55 +04:00
}
return 1 ;
}
2002-02-13 14:43:29 +03:00
static struct volume_group * _build_vg ( struct cmd_context * cmd ,
struct list * pvs )
2001-10-04 21:48:55 +04:00
{
2002-02-13 14:43:29 +03:00
struct pool * mem = cmd - > mem ;
2001-10-04 21:48:55 +04:00
struct volume_group * vg = pool_alloc ( mem , sizeof ( * vg ) ) ;
2001-10-09 21:09:46 +04:00
struct disk_list * dl ;
2002-01-29 20:23:33 +03:00
int partial ;
2001-10-09 21:09:46 +04:00
2001-10-15 22:39:40 +04:00
if ( ! vg )
goto bad ;
2001-10-04 21:48:55 +04:00
2001-10-15 22:39:40 +04:00
if ( list_empty ( pvs ) )
goto bad ;
2001-10-09 21:09:46 +04:00
2001-10-04 21:48:55 +04:00
memset ( vg , 0 , sizeof ( * vg ) ) ;
2002-02-13 14:43:29 +03:00
vg - > cmd = cmd ;
2001-10-31 15:47:01 +03:00
list_init ( & vg - > pvs ) ;
list_init ( & vg - > lvs ) ;
2002-02-13 14:43:29 +03:00
list_init ( & vg - > snapshots ) ;
2001-10-08 20:08:16 +04:00
2002-01-29 20:23:33 +03:00
if ( ! _check_vgs ( pvs , & partial ) )
2001-10-15 22:39:40 +04:00
goto bad ;
2001-10-09 18:26:45 +04:00
2002-01-29 20:23:33 +03:00
dl = list_item ( pvs - > n , struct disk_list ) ;
if ( ! import_vg ( mem , vg , dl , partial ) )
2001-10-04 21:48:55 +04:00
goto bad ;
2002-01-29 20:23:33 +03:00
if ( ! import_pvs ( mem , vg , pvs , & vg - > pvs , & vg - > pv_count ) )
2001-10-04 21:48:55 +04:00
goto bad ;
2001-10-09 18:26:45 +04:00
if ( ! import_lvs ( mem , vg , pvs ) )
2001-10-04 21:48:55 +04:00
goto bad ;
2001-10-09 18:26:45 +04:00
if ( ! import_extents ( mem , vg , pvs ) )
2001-10-08 13:45:16 +04:00
goto bad ;
2002-02-13 14:43:29 +03:00
if ( ! import_snapshots ( mem , vg , pvs ) )
goto bad ;
2001-10-04 21:48:55 +04:00
return vg ;
bad :
stack ;
pool_free ( mem , vg ) ;
return NULL ;
}
2001-11-12 15:16:57 +03:00
static struct volume_group * _vg_read ( struct format_instance * fi ,
const char * vg_name )
2001-10-04 21:48:55 +04:00
{
struct pool * mem = pool_create ( 1024 * 10 ) ;
2001-10-31 15:47:01 +03:00
struct list pvs ;
2001-11-12 18:10:01 +03:00
struct volume_group * vg = NULL ;
2001-10-31 15:47:01 +03:00
list_init ( & pvs ) ;
2001-10-04 21:48:55 +04:00
if ( ! mem ) {
stack ;
return NULL ;
}
2001-11-14 16:52:38 +03:00
/* Strip dev_dir if present */
2001-11-12 15:16:57 +03:00
vg_name = strip_dir ( vg_name , fi - > cmd - > dev_dir ) ;
2001-10-12 01:35:55 +04:00
2001-11-12 15:16:57 +03:00
if ( ! read_pvs_in_vg ( vg_name , fi - > cmd - > filter , mem , & pvs ) ) {
2001-10-04 21:48:55 +04:00
stack ;
2001-11-12 18:10:01 +03:00
goto bad ;
2001-10-04 21:48:55 +04:00
}
2002-02-13 14:43:29 +03:00
if ( ! ( vg = _build_vg ( fi - > cmd , & pvs ) ) ) {
2001-10-04 21:48:55 +04:00
stack ;
2001-11-12 18:10:01 +03:00
goto bad ;
}
bad :
2001-10-04 21:48:55 +04:00
pool_destroy ( mem ) ;
return vg ;
}
2001-10-08 13:45:16 +04:00
static struct disk_list * _flatten_pv ( struct pool * mem , struct volume_group * vg ,
2001-10-09 18:26:45 +04:00
struct physical_volume * pv ,
2001-11-14 16:52:38 +03:00
const char * dev_dir )
2001-10-05 20:36:53 +04:00
{
2001-10-09 14:47:52 +04:00
struct disk_list * dl = pool_alloc ( mem , sizeof ( * dl ) ) ;
2001-10-08 16:11:33 +04:00
2001-10-09 14:47:52 +04:00
if ( ! dl ) {
stack ;
return NULL ;
}
dl - > mem = mem ;
dl - > dev = pv - > dev ;
2001-10-31 15:47:01 +03:00
list_init ( & dl - > uuids ) ;
2001-10-31 20:59:52 +03:00
list_init ( & dl - > lvds ) ;
2001-10-09 14:47:52 +04:00
2002-01-29 20:23:33 +03:00
if ( ! export_pv ( mem , vg , & dl - > pvd , pv ) | |
2001-10-31 20:59:52 +03:00
! export_vg ( & dl - > vgd , vg ) | |
2001-10-09 18:26:45 +04:00
! export_uuids ( dl , vg ) | |
2001-11-14 16:52:38 +03:00
! export_lvs ( dl , vg , pv , dev_dir ) | |
2001-10-10 13:25:04 +04:00
! calculate_layout ( dl ) ) {
2001-10-09 14:47:52 +04:00
stack ;
2001-10-15 22:39:40 +04:00
pool_free ( mem , dl ) ;
2001-10-09 14:47:52 +04:00
return NULL ;
}
return dl ;
2001-10-05 20:36:53 +04:00
}
static int _flatten_vg ( struct pool * mem , struct volume_group * vg ,
2001-11-14 16:52:38 +03:00
struct list * pvds , const char * dev_dir ,
2001-10-11 18:10:18 +04:00
struct dev_filter * filter )
2001-10-05 20:36:53 +04:00
{
2001-10-31 15:47:01 +03:00
struct list * pvh ;
2001-10-09 14:47:52 +04:00
struct pv_list * pvl ;
2001-10-05 20:36:53 +04:00
struct disk_list * data ;
2001-10-31 15:47:01 +03:00
list_iterate ( pvh , & vg - > pvs ) {
pvl = list_item ( pvh , struct pv_list ) ;
2001-10-05 20:36:53 +04:00
2002-01-21 19:05:23 +03:00
if ( ! ( data = _flatten_pv ( mem , vg , pvl - > pv , dev_dir ) ) ) {
2001-10-05 20:36:53 +04:00
stack ;
return 0 ;
}
2001-11-14 16:52:38 +03:00
list_add ( pvds , & data - > list ) ;
2001-10-05 20:36:53 +04:00
}
2001-10-11 14:55:19 +04:00
2001-11-14 16:52:38 +03:00
export_numbers ( pvds , vg ) ;
export_pv_act ( pvds ) ;
2001-10-11 17:05:55 +04:00
2001-11-14 16:52:38 +03:00
if ( ! export_vg_number ( pvds , vg - > name , filter ) ) {
2001-10-11 18:10:18 +04:00
stack ;
return 0 ;
}
2001-10-05 20:36:53 +04:00
return 1 ;
}
2001-11-12 15:16:57 +03:00
static int _vg_write ( struct format_instance * fi , struct volume_group * vg )
2001-10-05 20:36:53 +04:00
{
struct pool * mem = pool_create ( 1024 * 10 ) ;
2001-11-14 16:52:38 +03:00
struct list pvds ;
2001-10-05 20:36:53 +04:00
int r = 0 ;
if ( ! mem ) {
stack ;
return 0 ;
}
2002-01-29 20:23:33 +03:00
if ( vg - > status & PARTIAL_VG ) {
log_error ( " Cannot change metadata for partial volume group %s " ,
vg - > name ) ;
return 0 ;
}
2001-11-14 16:52:38 +03:00
list_init ( & pvds ) ;
2001-10-10 17:09:40 +04:00
2001-11-14 16:52:38 +03:00
r = ( _flatten_vg ( mem , vg , & pvds , fi - > cmd - > dev_dir , fi - > cmd - > filter ) & &
write_disks ( & pvds ) ) ;
2001-10-05 20:36:53 +04:00
pool_destroy ( mem ) ;
return r ;
}
2001-10-04 21:48:55 +04:00
2001-11-12 15:16:57 +03:00
static struct physical_volume * _pv_read ( struct format_instance * fi ,
2001-10-09 20:05:34 +04:00
const char * name )
2001-10-09 12:58:52 +04:00
{
struct pool * mem = pool_create ( 1024 ) ;
2001-11-12 15:16:57 +03:00
struct physical_volume * pv = NULL ;
2001-10-09 12:58:52 +04:00
struct disk_list * dl ;
2001-10-09 20:05:34 +04:00
struct device * dev ;
2001-10-09 12:58:52 +04:00
2001-10-31 15:47:01 +03:00
log_very_verbose ( " Reading physical volume data %s from disk " , name ) ;
2001-10-17 19:29:31 +04:00
2001-10-09 12:58:52 +04:00
if ( ! mem ) {
stack ;
return NULL ;
}
2001-11-12 15:16:57 +03:00
if ( ! ( dev = dev_cache_get ( name , fi - > cmd - > filter ) ) ) {
2001-10-09 20:05:34 +04:00
stack ;
2001-11-12 15:16:57 +03:00
goto out ;
2001-10-09 20:05:34 +04:00
}
2001-11-02 19:28:04 +03:00
if ( ! ( dl = read_disk ( dev , mem , NULL ) ) ) {
2001-10-09 12:58:52 +04:00
stack ;
2001-11-12 15:16:57 +03:00
goto out ;
2001-10-09 12:58:52 +04:00
}
2001-11-12 15:16:57 +03:00
if ( ! ( pv = pool_alloc ( fi - > cmd - > mem , sizeof ( * pv ) ) ) ) {
2001-10-09 12:58:52 +04:00
stack ;
2001-11-12 15:16:57 +03:00
goto out ;
2001-10-09 12:58:52 +04:00
}
2002-01-29 20:23:33 +03:00
if ( ! import_pv ( fi - > cmd - > mem , dl - > dev , NULL , pv , & dl - > pvd ) ) {
2001-10-09 12:58:52 +04:00
stack ;
2001-11-12 15:16:57 +03:00
pool_free ( fi - > cmd - > mem , pv ) ;
pv = NULL ;
2001-10-09 12:58:52 +04:00
}
2001-11-12 15:16:57 +03:00
out :
2001-10-09 12:58:52 +04:00
pool_destroy ( mem ) ;
return pv ;
}
2001-11-12 15:16:57 +03:00
static struct list * _get_pvs ( struct format_instance * fi )
2001-10-08 21:53:43 +04:00
{
struct pool * mem = pool_create ( 1024 * 10 ) ;
2001-10-31 15:47:01 +03:00
struct list pvs , * results ;
2001-10-08 21:53:43 +04:00
uint32_t count ;
if ( ! mem ) {
stack ;
return NULL ;
}
2001-11-12 15:16:57 +03:00
if ( ! ( results = pool_alloc ( fi - > cmd - > mem , sizeof ( * results ) ) ) ) {
2001-10-08 21:53:43 +04:00
stack ;
2001-10-15 22:39:40 +04:00
pool_destroy ( mem ) ;
2001-10-08 21:53:43 +04:00
return NULL ;
}
2001-10-31 15:47:01 +03:00
list_init ( & pvs ) ;
list_init ( results ) ;
2001-10-08 21:53:43 +04:00
2001-11-12 15:16:57 +03:00
if ( ! read_pvs_in_vg ( NULL , fi - > cmd - > filter , mem , & pvs ) ) {
2001-10-08 21:53:43 +04:00
stack ;
goto bad ;
}
2002-01-29 20:23:33 +03:00
if ( ! import_pvs ( fi - > cmd - > mem , NULL , & pvs , results , & count ) ) {
2001-10-08 21:53:43 +04:00
stack ;
goto bad ;
}
pool_destroy ( mem ) ;
return results ;
bad :
2001-11-12 15:16:57 +03:00
pool_free ( fi - > cmd - > mem , results ) ;
2001-10-15 22:39:40 +04:00
pool_destroy ( mem ) ;
2001-10-08 21:53:43 +04:00
return NULL ;
}
2001-10-31 15:47:01 +03:00
static int _find_vg_name ( struct list * names , const char * vg )
2001-10-09 13:22:50 +04:00
{
2001-10-31 15:47:01 +03:00
struct list * nh ;
2001-10-09 13:22:50 +04:00
struct name_list * nl ;
2001-10-31 15:47:01 +03:00
list_iterate ( nh , names ) {
nl = list_item ( nh , struct name_list ) ;
2001-10-09 13:22:50 +04:00
if ( ! strcmp ( nl - > name , vg ) )
return 1 ;
}
return 0 ;
}
2001-11-12 15:16:57 +03:00
static struct list * _get_vgs ( struct format_instance * fi )
2001-10-09 13:22:50 +04:00
{
2001-10-31 15:47:01 +03:00
struct list * pvh ;
2001-11-12 15:16:57 +03:00
struct list * pvs , * names = pool_alloc ( fi - > cmd - > mem , sizeof ( * names ) ) ;
2001-10-09 13:22:50 +04:00
struct name_list * nl ;
if ( ! names ) {
stack ;
return NULL ;
}
2001-10-31 15:47:01 +03:00
list_init ( names ) ;
2001-10-09 13:22:50 +04:00
2001-11-12 15:16:57 +03:00
if ( ! ( pvs = _get_pvs ( fi ) ) ) {
2001-10-09 13:22:50 +04:00
stack ;
goto bad ;
}
2001-10-31 15:47:01 +03:00
list_iterate ( pvh , pvs ) {
struct pv_list * pvl = list_item ( pvh , struct pv_list ) ;
2001-10-09 13:22:50 +04:00
2002-01-21 19:05:23 +03:00
if ( ! ( * pvl - > pv - > vg_name ) | |
_find_vg_name ( names , pvl - > pv - > vg_name ) )
2001-10-09 13:22:50 +04:00
continue ;
2001-11-12 15:16:57 +03:00
if ( ! ( nl = pool_alloc ( fi - > cmd - > mem , sizeof ( * nl ) ) ) ) {
2001-10-09 13:22:50 +04:00
stack ;
goto bad ;
}
2002-01-21 19:05:23 +03:00
if ( ! ( nl - > name = pool_strdup ( fi - > cmd - > mem ,
pvl - > pv - > vg_name ) ) ) {
2001-10-09 13:22:50 +04:00
stack ;
goto bad ;
}
2001-10-31 15:47:01 +03:00
list_add ( names , & nl - > list ) ;
2001-10-09 13:22:50 +04:00
}
2001-10-16 20:25:28 +04:00
if ( list_empty ( names ) )
goto bad ;
2001-10-09 13:22:50 +04:00
return names ;
bad :
2001-11-12 15:16:57 +03:00
pool_free ( fi - > cmd - > mem , names ) ;
2001-10-09 13:22:50 +04:00
return NULL ;
}
2001-11-12 15:16:57 +03:00
static int _pv_setup ( struct format_instance * fi , struct physical_volume * pv ,
2001-10-10 13:25:04 +04:00
struct volume_group * vg )
{
2002-02-15 17:33:59 +03:00
/* setup operations for the PV structure */
2002-02-20 21:29:30 +03:00
if ( pv - > size > MAX_PV_SIZE )
pv - > size - - ;
2002-02-15 04:26:16 +03:00
if ( pv - > size > MAX_PV_SIZE ) {
2002-02-20 21:29:30 +03:00
/* FIXME Limit hardcoded */
log_error ( " Physical volumes cannot be bigger than 2TB " ) ;
2002-02-15 04:26:16 +03:00
return 0 ;
}
2002-02-20 21:29:30 +03:00
/* Nothing more to do if pe_size isn't known */
if ( ! vg )
return 1 ;
2002-02-15 17:33:59 +03:00
2001-10-10 14:55:55 +04:00
/*
* This works out pe_start and pe_count .
*/
if ( ! calculate_extent_count ( pv ) ) {
stack ;
return 0 ;
}
2001-10-10 13:25:04 +04:00
return 1 ;
}
2002-02-21 22:04:37 +03:00
static int _find_free_lvnum ( struct logical_volume * lv )
{
int lvnum_used [ MAX_LV ] ;
int i = 0 ;
struct list * lvh ;
struct lv_list * lvl ;
memset ( & lvnum_used , 0 , sizeof ( lvnum_used ) ) ;
list_iterate ( lvh , & lv - > vg - > lvs ) {
lvl = list_item ( lvh , struct lv_list ) ;
2002-03-05 23:03:09 +03:00
lvnum_used [ lvnum_from_lvid ( & lvl - > lv - > lvid ) ] = 1 ;
2002-02-21 22:04:37 +03:00
}
while ( lvnum_used [ i ] )
i + + ;
return i ;
}
2002-01-24 20:16:36 +03:00
static int _lv_setup ( struct format_instance * fi , struct logical_volume * lv )
{
2002-02-14 00:28:56 +03:00
uint64_t max_size = UINT_MAX ;
2002-03-05 23:03:09 +03:00
lvid_from_lvnum ( & lv - > lvid , & lv - > vg - > id , _find_free_lvnum ( lv ) ) ;
2002-02-21 22:04:37 +03:00
2002-01-24 22:20:35 +03:00
if ( lv - > le_count > MAX_LE_TOTAL ) {
2002-01-28 00:30:47 +03:00
log_error ( " logical volumes cannot contain more than "
" %d extents. " , MAX_LE_TOTAL ) ;
2002-01-24 20:16:36 +03:00
return 0 ;
}
2002-02-14 00:28:56 +03:00
if ( lv - > size > max_size ) {
char * dummy = display_size ( max_size , SIZE_SHORT ) ;
log_error ( " logical volumes cannot be larger than %s " , dummy ) ;
dbg_free ( dummy ) ;
return 0 ;
}
2002-01-24 20:16:36 +03:00
return 1 ;
}
2001-11-12 15:16:57 +03:00
static int _pv_write ( struct format_instance * fi , struct physical_volume * pv )
2001-10-09 21:44:58 +04:00
{
2001-10-10 14:05:29 +04:00
struct pool * mem ;
struct disk_list * dl ;
2001-10-31 15:47:01 +03:00
struct list pvs ;
2001-10-10 14:05:29 +04:00
2001-10-31 15:47:01 +03:00
list_init ( & pvs ) ;
2001-10-10 14:05:29 +04:00
2001-10-18 20:55:19 +04:00
if ( * pv - > vg_name | | pv - > pe_allocated ) {
2001-10-31 15:47:01 +03:00
log_error ( " Assertion failed: can't _pv_write non-orphan PV "
2001-10-12 01:35:55 +04:00
" (in VG %s) " , pv - > vg_name ) ;
2001-10-10 14:05:29 +04:00
return 0 ;
}
2001-10-18 20:55:19 +04:00
/* Ensure any residual PE structure is gone */
pv - > pe_size = pv - > pe_count = pv - > pe_start = 0 ;
2001-10-10 14:05:29 +04:00
if ( ! ( mem = pool_create ( 1024 ) ) ) {
stack ;
return 0 ;
}
if ( ! ( dl = pool_alloc ( mem , sizeof ( * dl ) ) ) ) {
stack ;
2001-10-15 22:39:40 +04:00
goto bad ;
2001-10-10 14:05:29 +04:00
}
dl - > mem = mem ;
dl - > dev = pv - > dev ;
2002-01-29 20:23:33 +03:00
if ( ! export_pv ( mem , NULL , & dl - > pvd , pv ) ) {
2001-10-10 14:05:29 +04:00
stack ;
goto bad ;
}
2002-01-29 18:52:11 +03:00
/* must be set to be able to zero gap after PV structure in
dev_write in order to make other disk tools happy */
dl - > pvd . pv_on_disk . base = METADATA_BASE ;
dl - > pvd . pv_on_disk . size = PV_SIZE ;
2001-10-31 15:47:01 +03:00
list_add ( & pvs , & dl - > list ) ;
2001-11-14 13:01:52 +03:00
if ( ! write_disks ( & pvs ) ) {
2001-10-10 14:05:29 +04:00
stack ;
goto bad ;
}
pool_destroy ( mem ) ;
2001-10-09 21:44:58 +04:00
return 1 ;
2001-10-10 14:05:29 +04:00
bad :
pool_destroy ( mem ) ;
return 0 ;
2001-10-09 21:44:58 +04:00
}
2001-11-12 15:16:57 +03:00
int _vg_setup ( struct format_instance * fi , struct volume_group * vg )
2001-10-12 18:25:53 +04:00
{
/* just check max_pv and max_lv */
2001-10-15 22:39:40 +04:00
if ( vg - > max_lv > = MAX_LV )
vg - > max_lv = MAX_LV - 1 ;
2001-10-12 18:25:53 +04:00
2001-10-15 22:39:40 +04:00
if ( vg - > max_pv > = MAX_PV )
vg - > max_pv = MAX_PV - 1 ;
2001-10-12 18:25:53 +04:00
2001-10-16 00:29:15 +04:00
if ( vg - > extent_size > MAX_PE_SIZE | | vg - > extent_size < MIN_PE_SIZE ) {
char * dummy , * dummy2 ;
log_error ( " Extent size must be between %s and %s " ,
2001-10-31 15:47:01 +03:00
( dummy = display_size ( MIN_PE_SIZE / 2 , SIZE_SHORT ) ) ,
2001-10-16 00:29:15 +04:00
( dummy2 = display_size ( MAX_PE_SIZE / 2 , SIZE_SHORT ) ) ) ;
dbg_free ( dummy ) ;
dbg_free ( dummy2 ) ;
return 0 ;
}
if ( vg - > extent_size % MIN_PE_SIZE ) {
char * dummy ;
log_error ( " Extent size must be multiple of %s " ,
( dummy = display_size ( MIN_PE_SIZE / 2 , SIZE_SHORT ) ) ) ;
dbg_free ( dummy ) ;
return 0 ;
}
/* Redundant? */
if ( vg - > extent_size & ( vg - > extent_size - 1 ) ) {
log_error ( " Extent size must be power of 2 " ) ;
return 0 ;
}
2001-10-12 18:25:53 +04:00
return 1 ;
}
2001-10-09 21:44:58 +04:00
2001-11-12 15:16:57 +03:00
void _destroy ( struct format_instance * fi )
2001-10-04 21:48:55 +04:00
{
2001-11-12 15:16:57 +03:00
dbg_free ( fi ) ;
2001-10-08 16:11:33 +04:00
}
2001-11-12 15:16:57 +03:00
static struct format_handler _format1_ops = {
get_vgs : _get_vgs ,
get_pvs : _get_pvs ,
pv_read : _pv_read ,
pv_setup : _pv_setup ,
pv_write : _pv_write ,
2002-01-24 20:16:36 +03:00
lv_setup : _lv_setup ,
2001-11-12 15:16:57 +03:00
vg_read : _vg_read ,
vg_setup : _vg_setup ,
vg_write : _vg_write ,
destroy : _destroy ,
} ;
2001-10-30 20:53:21 +03:00
2001-11-12 15:16:57 +03:00
struct format_instance * create_lvm1_format ( struct cmd_context * cmd )
{
struct format_instance * fi = dbg_malloc ( sizeof ( * fi ) ) ;
2001-10-08 16:11:33 +04:00
2001-11-12 15:16:57 +03:00
if ( ! fi ) {
2001-10-08 16:11:33 +04:00
stack ;
2001-11-12 15:16:57 +03:00
return NULL ;
2001-10-08 16:11:33 +04:00
}
2001-11-12 15:16:57 +03:00
fi - > cmd = cmd ;
fi - > ops = & _format1_ops ;
fi - > private = NULL ;
2001-10-08 16:11:33 +04:00
2001-11-12 15:16:57 +03:00
return fi ;
2001-10-04 21:48:55 +04:00
}