2001-09-25 16:49:28 +04:00
/*
2001-10-12 14:32:06 +04:00
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
2001-09-25 16:49:28 +04:00
*
2001-11-27 19:37:33 +03:00
* This file is released under the LGPL .
2001-09-25 16:49:28 +04:00
*
2001-10-02 02:12:10 +04:00
* This is the in core representation of a volume group and its
2001-09-28 17:15:30 +04:00
* associated physical and logical volumes .
2001-09-25 16:49:28 +04:00
*/
2001-10-01 19:14:39 +04:00
# ifndef _LVM_METADATA_H
# define _LVM_METADATA_H
2001-09-25 16:49:28 +04:00
2001-10-02 02:12:10 +04:00
# include <sys/types.h>
2001-12-03 19:27:16 +03:00
# include <asm/page.h>
2001-10-01 20:21:21 +04:00
# include "dev-cache.h"
2001-10-02 21:09:05 +04:00
# include "list.h"
2001-10-12 14:32:06 +04:00
# include "uuid.h"
2001-10-01 20:21:21 +04:00
2001-10-02 21:09:05 +04:00
# define NAME_LEN 128
2001-12-03 19:27:16 +03:00
# define MAX_STRIPES 128
# define SECTOR_SIZE 512
# define STRIPE_SIZE_DEFAULT 16 /* 16KB */
# define STRIPE_SIZE_MIN ( PAGE_SIZE / SECTOR_SIZE) /* PAGESIZE in sectors */
# define STRIPE_SIZE_MAX ( 512L * 1024 / SECTOR_SIZE) /* 512 KB in sectors */
2002-02-15 04:26:16 +03:00
# define PV_MIN_SIZE ( 512L * 1024 / SECTOR_SIZE) /* 512 KB in sectors */
2002-04-24 22:20:51 +04:00
# define PE_ALIGN (65536UL / SECTOR_SIZE) /* PE alignment */
2001-12-03 19:27:16 +03:00
2001-10-02 02:12:10 +04:00
/* Various flags */
/* Note that the bits no longer necessarily correspond to LVM1 disk format */
2002-07-11 18:36:45 +04:00
# define BIT(x) (1 << x)
# define EXPORTED_VG BIT(0) /* VG PV */
# define RESIZEABLE_VG BIT(1) /* VG */
# define PARTIAL_VG BIT(2) /* VG */
/*
* May any free extents on this PV be used or must they be left
* free ?
*/
# define ALLOCATABLE_PV BIT(3) /* PV */
# define SPINDOWN_LV BIT(4) /* LV */
# define BADBLOCK_ON BIT(5) /* LV */
# define FIXED_MINOR BIT(6) /* LV */
2002-07-11 19:28:49 +04:00
# define VISIBLE_LV BIT(7) /* LV */
2002-07-11 18:36:45 +04:00
/*
* FIXME : do we really set read / write for a whole vg ?
*/
# define LVM_READ BIT(8) /* LV VG */
# define LVM_WRITE BIT(9) /* LV VG */
# define CLUSTERED BIT(10) /* VG */
# define SHARED BIT(11) /* VG */
2001-10-02 02:12:10 +04:00
2002-04-24 22:20:51 +04:00
# define FMT_SEGMENTS 0x00000001 /* Arbitrary segment parameters? */
# define FMT_TEXT_NAME "text"
# define FMT_LVM1_NAME "lvm1"
2001-10-02 02:12:10 +04:00
2002-07-11 18:21:49 +04:00
typedef enum {
ALLOC_NEXT_FREE ,
ALLOC_STRICT ,
ALLOC_CONTIGUOUS
} alloc_policy_t ;
2001-09-28 17:15:30 +04:00
struct physical_volume {
2001-10-08 20:08:16 +04:00
struct id id ;
2001-09-28 17:15:30 +04:00
struct device * dev ;
2002-04-24 22:20:51 +04:00
struct format_instance * fid ;
2001-10-12 14:32:06 +04:00
char * vg_name ;
2001-09-25 16:49:28 +04:00
2001-10-04 14:13:07 +04:00
uint32_t status ;
uint64_t size ;
2001-09-25 16:49:28 +04:00
2001-09-28 17:15:30 +04:00
/* physical extents */
2001-10-04 14:13:07 +04:00
uint64_t pe_size ;
uint64_t pe_start ;
uint32_t pe_count ;
2002-04-24 22:20:51 +04:00
uint32_t pe_alloc_count ;
2001-11-26 15:49:29 +03:00
} ;
2001-11-12 15:16:57 +03:00
struct cmd_context ;
2002-04-24 22:20:51 +04:00
struct format_type {
struct cmd_context * cmd ;
struct format_handler * ops ;
const char * name ;
uint32_t features ;
void * private ;
} ;
struct metadata_area {
struct list list ;
void * metadata_locn ;
} ;
struct format_instance {
struct format_type * fmt ;
struct list metadata_areas ; /* e.g. metadata locations */
} ;
2001-09-28 17:15:30 +04:00
struct volume_group {
2001-11-12 15:16:57 +03:00
struct cmd_context * cmd ;
2002-04-24 22:20:51 +04:00
struct format_instance * fid ;
uint32_t seqno ; /* Metadata sequence number */
2001-11-12 15:16:57 +03:00
2001-10-08 20:08:16 +04:00
struct id id ;
2001-10-12 14:32:06 +04:00
char * name ;
2002-01-29 20:23:33 +03:00
char * system_id ;
2001-09-25 16:49:28 +04:00
2001-10-04 14:13:07 +04:00
uint32_t status ;
2001-10-03 16:34:08 +04:00
2001-11-06 22:02:26 +03:00
uint32_t extent_size ;
2001-10-04 14:13:07 +04:00
uint32_t extent_count ;
uint32_t free_count ;
2001-09-25 16:49:28 +04:00
2001-10-04 14:13:07 +04:00
uint32_t max_lv ;
uint32_t max_pv ;
2001-10-04 00:38:07 +04:00
2001-09-28 17:15:30 +04:00
/* physical volumes */
2001-10-04 14:13:07 +04:00
uint32_t pv_count ;
2001-10-31 15:47:01 +03:00
struct list pvs ;
2001-09-25 16:49:28 +04:00
2001-09-28 17:15:30 +04:00
/* logical volumes */
2001-10-04 14:13:07 +04:00
uint32_t lv_count ;
2001-10-31 15:47:01 +03:00
struct list lvs ;
2002-02-12 19:31:31 +03:00
/* snapshots */
uint32_t snapshot_count ;
struct list snapshots ;
2001-09-28 17:15:30 +04:00
} ;
2001-09-25 16:49:28 +04:00
2001-11-27 19:37:33 +03:00
struct stripe_segment {
struct list list ;
struct logical_volume * lv ;
uint32_t le ;
uint32_t len ;
uint32_t stripe_size ;
uint32_t stripes ;
/* There will be one area for each stripe */
struct {
struct physical_volume * pv ;
uint32_t pe ;
} area [ 0 ] ;
} ;
2001-10-31 20:59:52 +03:00
struct logical_volume {
2002-03-05 23:03:09 +03:00
union lvid lvid ;
2001-10-31 20:59:52 +03:00
char * name ;
struct volume_group * vg ;
uint32_t status ;
2002-07-11 18:21:49 +04:00
alloc_policy_t alloc ;
2001-10-31 20:59:52 +03:00
uint32_t read_ahead ;
2002-02-01 20:54:39 +03:00
int32_t minor ;
2001-10-31 20:59:52 +03:00
uint64_t size ;
uint32_t le_count ;
2001-11-26 19:18:48 +03:00
struct list segments ;
2001-10-31 20:59:52 +03:00
} ;
2002-02-12 19:31:31 +03:00
struct snapshot {
int persistent ; /* boolean */
uint32_t chunk_size ; /* in 512 byte sectors */
struct logical_volume * origin ;
struct logical_volume * cow ;
} ;
2001-10-05 02:53:37 +04:00
struct name_list {
2001-10-31 15:47:01 +03:00
struct list list ;
2001-10-08 20:08:16 +04:00
char * name ;
2001-10-02 21:09:05 +04:00
} ;
struct pv_list {
2001-10-31 15:47:01 +03:00
struct list list ;
2002-01-21 19:05:23 +03:00
struct physical_volume * pv ;
2001-10-02 21:09:05 +04:00
} ;
2001-10-02 02:12:10 +04:00
2001-10-08 13:45:16 +04:00
struct lv_list {
2001-10-31 15:47:01 +03:00
struct list list ;
2002-01-21 19:49:32 +03:00
struct logical_volume * lv ;
2001-10-08 13:45:16 +04:00
} ;
2002-02-12 19:31:31 +03:00
struct snapshot_list {
struct list list ;
struct snapshot * snapshot ;
} ;
2001-11-12 15:16:57 +03:00
2001-10-10 13:25:04 +04:00
/*
* Ownership of objects passes to caller .
*/
2001-11-12 15:16:57 +03:00
struct format_handler {
2001-10-10 13:25:04 +04:00
/*
* Returns a name_list of vg ' s .
*/
2002-04-24 22:20:51 +04:00
struct list * ( * get_vgs ) ( struct format_type * fmt , struct list * names ) ;
2001-10-05 02:53:37 +04:00
2001-10-10 13:25:04 +04:00
/*
* Returns pv_list of fully - populated pv structures .
*/
2002-04-24 22:20:51 +04:00
struct list * ( * get_pvs ) ( struct format_type * fmt , struct list * results ) ;
2001-09-25 16:49:28 +04:00
2001-10-10 13:25:04 +04:00
/*
* Return PV with given path .
*/
2002-04-24 22:20:51 +04:00
int ( * pv_read ) ( struct format_type * fmt ,
const char * pv_name ,
struct physical_volume * pv ) ;
2001-10-05 02:53:37 +04:00
2001-10-10 13:25:04 +04:00
/*
2001-11-12 15:16:57 +03:00
* Tweak an already filled out a pv ready for importing into a
* vg . eg . pe_count is format specific .
2001-10-10 13:25:04 +04:00
*/
2001-11-12 15:16:57 +03:00
int ( * pv_setup ) ( struct format_instance * fi , struct physical_volume * pv ,
2001-10-10 13:25:04 +04:00
struct volume_group * vg ) ;
/*
2001-11-12 15:16:57 +03:00
* Write a PV structure to disk . Fails if the PV is in a VG ie
* pv - > vg_name must be null .
2001-10-10 13:25:04 +04:00
*/
2002-04-24 22:20:51 +04:00
int ( * pv_write ) ( struct format_instance * fi , struct physical_volume * pv ,
void * mdl ) ;
int ( * pv_commit ) ( struct format_instance * fid ,
struct physical_volume * pv , void * mdl ) ;
2001-09-25 16:49:28 +04:00
2002-01-24 20:15:49 +03:00
/*
* Tweak an already filled out a lv eg , check there
* aren ' t too many extents .
*/
int ( * lv_setup ) ( struct format_instance * fi , struct logical_volume * lv ) ;
2001-10-12 18:25:53 +04:00
/*
2001-11-12 15:16:57 +03:00
* Tweak an already filled out vg . eg , max_pv is format
* specific .
2001-10-12 18:25:53 +04:00
*/
2001-11-12 15:16:57 +03:00
int ( * vg_setup ) ( struct format_instance * fi , struct volume_group * vg ) ;
2002-04-24 22:20:51 +04:00
int ( * vg_remove ) ( struct format_instance * fi , struct volume_group * vg ,
void * mdl ) ;
2001-10-12 18:25:53 +04:00
2001-10-10 13:25:04 +04:00
/*
2001-11-12 15:16:57 +03:00
* The name may be prefixed with the dev_dir from the
* job_context .
2002-04-24 22:20:51 +04:00
* mdl is the metadata location to use
2001-10-10 13:25:04 +04:00
*/
2001-11-12 15:16:57 +03:00
struct volume_group * ( * vg_read ) ( struct format_instance * fi ,
2002-04-24 22:20:51 +04:00
const char * vg_name , void * mdl ) ;
2001-10-05 02:53:37 +04:00
2001-10-10 13:25:04 +04:00
/*
2001-11-12 15:16:57 +03:00
* Write out complete VG metadata . You must ensure internal
* consistency before calling . eg . PEs can ' t refer to PVs not
* part of the VG .
*
* It is also the responsibility of the caller to ensure external
* consistency , eg by calling pv_write ( ) if removing PVs from
* a VG or calling vg_write ( ) a second time if splitting a VG
* into two .
*
* vg_write ( ) must not read or write from any PVs not included
* in the volume_group structure it is handed . Note : format1
* does read all pv ' s currently .
2001-10-05 02:53:37 +04:00
*/
2002-04-24 22:20:51 +04:00
int ( * vg_write ) ( struct format_instance * fid , struct volume_group * vg ,
void * mdl ) ;
int ( * vg_commit ) ( struct format_instance * fid , struct volume_group * vg ,
void * mdl ) ;
/*
* Create format instance with a particular metadata area
*/
struct format_instance * ( * create_instance ) ( struct format_type * fmt ,
const char * vgname ,
void * context ) ;
/*
* Destructor for format instance
*/
void ( * destroy_instance ) ( struct format_instance * fid ) ;
2001-10-05 02:53:37 +04:00
2001-10-10 13:25:04 +04:00
/*
2002-04-24 22:20:51 +04:00
* Destructor for format type
2001-10-10 13:25:04 +04:00
*/
2002-04-24 22:20:51 +04:00
void ( * destroy ) ( struct format_type * fmt ) ;
2001-09-28 17:15:30 +04:00
} ;
2001-09-25 16:49:28 +04:00
2001-10-12 14:32:06 +04:00
/*
* Utility functions
*/
2002-04-24 22:20:51 +04:00
int vg_write ( struct volume_group * vg ) ;
struct volume_group * vg_read ( struct cmd_context * cmd , const char * vg_name ) ;
struct volume_group * vg_read_by_vgid ( struct cmd_context * cmd , const char * vgid ) ;
struct physical_volume * pv_read ( struct cmd_context * cmd , const char * pv_name ) ;
struct list * get_pvs ( struct cmd_context * cmd ) ;
struct list * get_vgs ( struct cmd_context * cmd ) ;
int pv_write ( struct cmd_context * cmd , struct physical_volume * pv ) ;
2001-11-12 15:16:57 +03:00
struct physical_volume * pv_create ( struct format_instance * fi ,
2002-01-16 21:10:08 +03:00
const char * name ,
2002-02-15 04:26:16 +03:00
struct id * id ,
uint64_t size ) ;
2001-11-12 15:16:57 +03:00
2002-04-24 22:20:51 +04:00
struct volume_group * vg_create ( struct cmd_context * cmd , const char * name ,
2001-11-06 22:02:26 +03:00
uint32_t extent_size , int max_pv , int max_lv ,
2001-10-12 18:25:53 +04:00
int pv_count , char * * pv_names ) ;
2002-04-24 22:20:51 +04:00
int vg_remove ( struct volume_group * vg ) ;
2001-11-12 15:16:57 +03:00
/*
* This needs the format instance to check the
* pv ' s are orphaned .
*/
int vg_extend ( struct format_instance * fi ,
struct volume_group * vg , int pv_count , char * * pv_names ) ;
2001-10-12 14:32:06 +04:00
2001-11-05 19:41:38 +03:00
/*
2001-11-06 22:02:26 +03:00
* Create a new LV within a given volume group .
*
2001-11-05 19:41:38 +03:00
*/
2002-01-24 20:15:49 +03:00
struct logical_volume * lv_create ( struct format_instance * fi ,
const char * name ,
2001-11-05 19:41:38 +03:00
uint32_t status ,
2002-07-11 18:21:49 +04:00
alloc_policy_t alloc ,
2001-11-05 19:41:38 +03:00
uint32_t stripes ,
uint32_t stripe_size ,
2001-11-06 13:29:56 +03:00
uint32_t extents ,
2001-11-05 19:41:38 +03:00
struct volume_group * vg ,
2001-11-06 14:19:33 +03:00
struct list * acceptable_pvs ) ;
2002-02-08 14:13:47 +03:00
int lv_reduce ( struct format_instance * fi ,
2002-01-24 20:15:49 +03:00
struct logical_volume * lv , uint32_t extents ) ;
2001-11-06 14:19:33 +03:00
2002-01-24 20:15:49 +03:00
int lv_extend ( struct format_instance * fi ,
struct logical_volume * lv ,
2001-11-26 18:31:46 +03:00
uint32_t stripes ,
uint32_t stripe_size ,
2001-12-20 14:52:54 +03:00
uint32_t extents ,
2001-11-26 18:31:46 +03:00
struct list * allocatable_pvs ) ;
2001-10-12 14:32:06 +04:00
2001-11-14 21:38:07 +03:00
/* lv must be part of vg->lvs */
int lv_remove ( struct volume_group * vg , struct logical_volume * lv ) ;
2001-11-12 22:28:50 +03:00
2001-11-06 22:02:26 +03:00
2001-10-02 02:12:10 +04:00
/* FIXME: Move to other files */
2001-09-28 17:15:30 +04:00
int id_eq ( struct id * op1 , struct id * op2 ) ;
2001-10-05 02:53:37 +04:00
/* Manipulate PV structures */
2001-10-02 02:12:10 +04:00
int pv_add ( struct volume_group * vg , struct physical_volume * pv ) ;
2001-10-03 16:34:08 +04:00
int pv_remove ( struct volume_group * vg , struct physical_volume * pv ) ;
2001-10-02 02:12:10 +04:00
struct physical_volume * pv_find ( struct volume_group * vg ,
2001-10-03 16:34:08 +04:00
const char * pv_name ) ;
2001-09-25 16:49:28 +04:00
2001-10-05 02:53:37 +04:00
2001-10-29 16:52:23 +03:00
/* Find a PV within a given VG */
2002-01-21 17:28:12 +03:00
struct pv_list * find_pv_in_vg ( struct volume_group * vg , const char * pv_name ) ;
2001-10-05 02:53:37 +04:00
/* Find an LV within a given VG */
2002-01-21 17:28:12 +03:00
struct lv_list * find_lv_in_vg ( struct volume_group * vg , const char * lv_name ) ;
2002-03-05 23:03:09 +03:00
struct lv_list * find_lv_in_vg_by_lvid ( struct volume_group * vg ,
union lvid * lvid ) ;
2001-10-29 16:52:23 +03:00
/* Return the VG that contains a given LV (based on path given in lv_name) */
/* or environment var */
struct volume_group * find_vg_with_lv ( const char * lv_name ) ;
/* FIXME Merge these functions with ones above */
2001-11-27 19:37:33 +03:00
struct physical_volume * find_pv ( struct volume_group * vg , struct device * dev ) ;
2001-10-29 16:52:23 +03:00
struct logical_volume * find_lv ( struct volume_group * vg , const char * lv_name ) ;
2001-09-28 17:15:30 +04:00
2001-11-12 15:16:57 +03:00
/*
2001-11-14 16:52:38 +03:00
* Remove a dev_dir if present .
2001-11-12 15:16:57 +03:00
*/
const char * strip_dir ( const char * vg_name , const char * dir ) ;
2001-10-15 22:39:40 +04:00
2002-01-10 14:18:08 +03:00
/*
* Checks that an lv has no gaps or overlapping segments .
*/
int lv_check_segments ( struct logical_volume * lv ) ;
/*
* Sometimes ( eg , after an lvextend ) , it is possible to merge two
* adjacent segments into a single segment . This function trys
* to merge as many segments as possible .
*/
int lv_merge_segments ( struct logical_volume * lv ) ;
2002-02-12 19:31:31 +03:00
/*
* Useful functions for managing snapshots .
*/
2002-02-20 22:04:55 +03:00
int lv_is_origin ( struct logical_volume * lv ) ;
int lv_is_cow ( struct logical_volume * lv ) ;
2002-02-12 19:31:31 +03:00
2002-02-25 14:55:39 +03:00
struct snapshot * find_cow ( struct logical_volume * lv ) ;
2002-04-24 22:20:51 +04:00
struct snapshot * find_origin ( struct logical_volume * lv ) ;
2002-05-08 20:57:46 +04:00
struct list * find_snapshots ( struct logical_volume * lv ) ;
2002-02-21 13:16:33 +03:00
2002-02-21 21:31:48 +03:00
int vg_add_snapshot ( struct logical_volume * origin ,
2002-02-12 19:31:31 +03:00
struct logical_volume * cow ,
int persistent ,
uint32_t chunk_size ) ;
int vg_remove_snapshot ( struct volume_group * vg , struct logical_volume * cow ) ;
2001-09-28 17:15:30 +04:00
# endif