2018-05-01 22:32:15 +03:00
/*
* Copyright ( C ) 2018 Red Hat , Inc . All rights reserved .
*
* 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
* of the GNU Lesser General Public License v .2 .1 .
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
2018-05-14 12:30:20 +03:00
# include "lib/misc/lib.h"
# include "lib/device/dev-type.h"
# include "lib/mm/xlate.h"
2018-05-01 22:32:15 +03:00
/*
* These lvm1 structs just used NAME_LEN in the previous format1 lvm2 code , but
* NAME_LEN was defined as 128 in generic lvm2 code that was not lvm1 - specific
* and not disk - format - specific .
*/
# define LVM1_NAME_LEN 128
struct data_area {
uint32_t base ;
uint32_t size ;
} __attribute__ ( ( packed ) ) ;
struct pv_disk {
int8_t id [ 2 ] ;
uint16_t version ; /* lvm version */
struct data_area pv_on_disk ;
struct data_area vg_on_disk ;
struct data_area pv_uuidlist_on_disk ;
struct data_area lv_on_disk ;
struct data_area pe_on_disk ;
int8_t pv_uuid [ LVM1_NAME_LEN ] ;
int8_t vg_name [ LVM1_NAME_LEN ] ;
int8_t system_id [ LVM1_NAME_LEN ] ; /* for vgexport/vgimport */
uint32_t pv_major ;
uint32_t pv_number ;
uint32_t pv_status ;
uint32_t pv_allocatable ;
uint32_t pv_size ;
uint32_t lv_cur ;
uint32_t pe_size ;
uint32_t pe_total ;
uint32_t pe_allocated ;
/* only present on version == 2 pv's */
uint32_t pe_start ;
} __attribute__ ( ( packed ) ) ;
int dev_is_lvm1 ( struct device * dev , char * buf , int buflen )
{
struct pv_disk * pvd = ( struct pv_disk * ) buf ;
uint32_t version ;
int ret ;
version = xlate16 ( pvd - > version ) ;
if ( pvd - > id [ 0 ] = = ' H ' & & pvd - > id [ 1 ] = = ' M ' & &
( version = = 1 | | version = = 2 ) )
ret = 1 ;
else
ret = 0 ;
return ret ;
}
# define POOL_MAGIC 0x011670
# define POOL_NAME_SIZE 256
# define NSPMajorVersion 4
# define NSPMinorVersion 1
# define NSPUpdateLevel 3
/* When checking for version matching, the first two numbers **
* * are important for metadata formats , a . k . a pool labels . * *
* * All the numbers are important when checking if the user * *
* * space tools match up with the kernel module . . . . . . . . . . . . . */
# define POOL_VERSION (NSPMajorVersion << 16 | \
NSPMinorVersion < < 8 | \
NSPUpdateLevel )
struct pool_disk {
uint64_t pl_magic ; /* Pool magic number */
uint64_t pl_pool_id ; /* Unique pool identifier */
char pl_pool_name [ POOL_NAME_SIZE ] ; /* Name of pool */
uint32_t pl_version ; /* Pool version */
uint32_t pl_subpools ; /* Number of subpools in this pool */
uint32_t pl_sp_id ; /* Subpool number within pool */
uint32_t pl_sp_devs ; /* Number of data partitions in this subpool */
uint32_t pl_sp_devid ; /* Partition number within subpool */
uint32_t pl_sp_type ; /* Partition type */
uint64_t pl_blocks ; /* Number of blocks in this partition */
uint32_t pl_striping ; /* Striping size within subpool */
/*
* If the number of DMEP devices is zero , then the next field * *
* * * ( pl_sp_dmepid ) becomes the subpool ID for redirection . In * *
* * * other words , if this subpool does not have the capability * *
* * * to do DMEP , then it must specify which subpool will do it * *
* * * in it ' s place
*/
/*
* While the next 3 field are no longer used , they must stay to keep * *
* * * backward compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
*/
uint32_t pl_sp_dmepdevs ; /* Number of dmep devices in this subpool */
uint32_t pl_sp_dmepid ; /* Dmep device number within subpool */
uint32_t pl_sp_weight ; /* if dmep dev, pref to using it */
uint32_t pl_minor ; /* the pool minor number */
uint32_t pl_padding ; /* reminder - think about alignment */
/*
* Even though we ' re zeroing out 8 k at the front of the disk before
* writing the label , putting this in
*/
char pl_reserve [ 184 ] ; /* bump the structure size out to 512 bytes */
} ;
# define CPIN_8(x, y, z) {memcpy((x), (y), (z));}
# define CPIN_16(x, y) {(x) = xlate16_be((y));}
# define CPIN_32(x, y) {(x) = xlate32_be((y));}
# define CPIN_64(x, y) {(x) = xlate64_be((y));}
static void pool_label_in ( struct pool_disk * pl , void * buf )
{
struct pool_disk * bufpl = ( struct pool_disk * ) buf ;
CPIN_64 ( pl - > pl_magic , bufpl - > pl_magic ) ;
CPIN_64 ( pl - > pl_pool_id , bufpl - > pl_pool_id ) ;
CPIN_8 ( pl - > pl_pool_name , bufpl - > pl_pool_name , POOL_NAME_SIZE ) ;
CPIN_32 ( pl - > pl_version , bufpl - > pl_version ) ;
CPIN_32 ( pl - > pl_subpools , bufpl - > pl_subpools ) ;
CPIN_32 ( pl - > pl_sp_id , bufpl - > pl_sp_id ) ;
CPIN_32 ( pl - > pl_sp_devs , bufpl - > pl_sp_devs ) ;
CPIN_32 ( pl - > pl_sp_devid , bufpl - > pl_sp_devid ) ;
CPIN_32 ( pl - > pl_sp_type , bufpl - > pl_sp_type ) ;
CPIN_64 ( pl - > pl_blocks , bufpl - > pl_blocks ) ;
CPIN_32 ( pl - > pl_striping , bufpl - > pl_striping ) ;
CPIN_32 ( pl - > pl_sp_dmepdevs , bufpl - > pl_sp_dmepdevs ) ;
CPIN_32 ( pl - > pl_sp_dmepid , bufpl - > pl_sp_dmepid ) ;
CPIN_32 ( pl - > pl_sp_weight , bufpl - > pl_sp_weight ) ;
CPIN_32 ( pl - > pl_minor , bufpl - > pl_minor ) ;
CPIN_32 ( pl - > pl_padding , bufpl - > pl_padding ) ;
CPIN_8 ( pl - > pl_reserve , bufpl - > pl_reserve , 184 ) ;
}
int dev_is_pool ( struct device * dev , char * buf , int buflen )
{
struct pool_disk pd ;
int ret ;
pool_label_in ( & pd , buf ) ;
/* can ignore 8 rightmost bits for ondisk format check */
if ( ( pd . pl_magic = = POOL_MAGIC ) & &
( pd . pl_version > > 8 = = POOL_VERSION > > 8 ) )
ret = 1 ;
else
ret = 0 ;
return ret ;
}