Home | History | Annotate | Line # | Download | only in include
metadata-exported.h revision 1.1.1.1.2.1
      1 /*	$NetBSD: metadata-exported.h,v 1.1.1.1.2.1 2009/05/13 18:52:41 jym Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
      5  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
      6  *
      7  * This file is part of LVM2.
      8  *
      9  * This copyrighted material is made available to anyone wishing to use,
     10  * modify, copy, or redistribute it subject to the terms and conditions
     11  * of the GNU Lesser General Public License v.2.1.
     12  *
     13  * You should have received a copy of the GNU Lesser General Public License
     14  * along with this program; if not, write to the Free Software Foundation,
     15  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     16  */
     17 
     18 /*
     19  * This is the representation of LVM metadata that is being adapted
     20  * for library export.
     21  */
     22 
     23 #ifndef _LVM_METADATA_EXPORTED_H
     24 #define _LVM_METADATA_EXPORTED_H
     25 
     26 #include "uuid.h"
     27 
     28 struct physical_volume;
     29 typedef struct physical_volume pv_t;
     30 struct volume_group;
     31 typedef struct volume_group vg_t;
     32 
     33 struct logical_volume;
     34 
     35 struct lv_segment;
     36 struct pv_segment;
     37 
     38 #define MAX_STRIPES 128U
     39 #define SECTOR_SHIFT 9L
     40 #define STRIPE_SIZE_MIN ( (unsigned) lvm_getpagesize() >> SECTOR_SHIFT)	/* PAGESIZE in sectors */
     41 #define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT)	/* 512 KB in sectors */
     42 #define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
     43 #define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT)	/* 512 KB in sectors */
     44 #define MAX_RESTRICTED_LVS 255	/* Used by FMT_RESTRICTED_LVIDS */
     45 
     46 /* Layer suffix */
     47 #define MIRROR_SYNC_LAYER "_mimagetmp"
     48 
     49 /* Various flags */
     50 /* Note that the bits no longer necessarily correspond to LVM1 disk format */
     51 
     52 #define PARTIAL_VG		0x00000001U	/* VG */
     53 #define EXPORTED_VG          	0x00000002U	/* VG PV */
     54 #define RESIZEABLE_VG        	0x00000004U	/* VG */
     55 
     56 /* May any free extents on this PV be used or must they be left free? */
     57 #define ALLOCATABLE_PV         	0x00000008U	/* PV */
     58 
     59 //#define SPINDOWN_LV          	0x00000010U	/* LV */
     60 //#define BADBLOCK_ON       	0x00000020U	/* LV */
     61 #define VISIBLE_LV		0x00000040U	/* LV */
     62 #define FIXED_MINOR		0x00000080U	/* LV */
     63 /* FIXME Remove when metadata restructuring is completed */
     64 #define SNAPSHOT		0x00001000U	/* LV - internal use only */
     65 #define PVMOVE			0x00002000U	/* VG LV SEG */
     66 #define LOCKED			0x00004000U	/* LV */
     67 #define MIRRORED		0x00008000U	/* LV - internal use only */
     68 //#define VIRTUAL			0x00010000U	/* LV - internal use only */
     69 #define MIRROR_LOG		0x00020000U	/* LV */
     70 #define MIRROR_IMAGE		0x00040000U	/* LV */
     71 #define MIRROR_NOTSYNCED	0x00080000U	/* LV */
     72 //#define ACTIVATE_EXCL		0x00100000U	/* LV - internal use only */
     73 //#define PRECOMMITTED		0x00200000U	/* VG - internal use only */
     74 #define CONVERTING		0x00400000U	/* LV */
     75 
     76 #define MISSING_PV              0x00800000U	/* PV */
     77 #define PARTIAL_LV              0x01000000U	/* LV - derived flag, not
     78 						   written out in metadata*/
     79 
     80 //#define POSTORDER_FLAG	0x02000000U /* Not real flags, reserved for
     81 //#define POSTORDER_OPEN_FLAG	0x04000000U    temporary use inside vg_read. */
     82 
     83 #define LVM_READ              	0x00000100U	/* LV VG */
     84 #define LVM_WRITE             	0x00000200U	/* LV VG */
     85 #define CLUSTERED         	0x00000400U	/* VG */
     86 //#define SHARED            	0x00000800U	/* VG */
     87 
     88 /* Format features flags */
     89 #define FMT_SEGMENTS		0x00000001U	/* Arbitrary segment params? */
     90 #define FMT_MDAS		0x00000002U	/* Proper metadata areas? */
     91 #define FMT_TAGS		0x00000004U	/* Tagging? */
     92 #define FMT_UNLIMITED_VOLS	0x00000008U	/* Unlimited PVs/LVs? */
     93 #define FMT_RESTRICTED_LVIDS	0x00000010U	/* LVID <= 255 */
     94 #define FMT_ORPHAN_ALLOCATABLE	0x00000020U	/* Orphan PV allocatable? */
     95 //#define FMT_PRECOMMIT		0x00000040U	/* Supports pre-commit? */
     96 #define FMT_RESIZE_PV		0x00000080U	/* Supports pvresize? */
     97 #define FMT_UNLIMITED_STRIPESIZE 0x00000100U	/* Unlimited stripe size? */
     98 #define FMT_RESTRICTED_READAHEAD 0x00000200U	/* Readahead restricted to 2-120? */
     99 
    100 /* LVM2 external library flags */
    101 #define CORRECT_INCONSISTENT    0x00000001U /* Correct inconsistent metadata */
    102 #define FAIL_INCONSISTENT       0x00000002U /* Fail if metadata inconsistent */
    103 
    104 /* Mirror conversion type flags */
    105 #define MIRROR_BY_SEG		0x00000001U	/* segment-by-segment mirror */
    106 #define MIRROR_BY_LV		0x00000002U	/* mirror using whole mimage LVs */
    107 #define MIRROR_SKIP_INIT_SYNC	0x00000010U	/* skip initial sync */
    108 
    109 /* Ordered list - see lv_manip.c */
    110 typedef enum {
    111 	ALLOC_INVALID,
    112 	ALLOC_CONTIGUOUS,
    113 	ALLOC_CLING,
    114 	ALLOC_NORMAL,
    115 	ALLOC_ANYWHERE,
    116 	ALLOC_INHERIT
    117 } alloc_policy_t;
    118 
    119 typedef enum {
    120 	AREA_UNASSIGNED,
    121 	AREA_PV,
    122 	AREA_LV
    123 } area_type_t;
    124 
    125 /*
    126  * Whether or not to force an operation.
    127  */
    128 typedef enum {
    129 	PROMPT = 0, /* Issue yes/no prompt to confirm operation */
    130 	DONT_PROMPT = 1, /* Skip yes/no prompt */
    131 	DONT_PROMPT_OVERRIDE = 2 /* Skip prompt + override a second condition */
    132 } force_t;
    133 
    134 struct cmd_context;
    135 struct format_handler;
    136 struct labeller;
    137 
    138 struct format_type {
    139 	struct dm_list list;
    140 	struct cmd_context *cmd;
    141 	struct format_handler *ops;
    142 	struct labeller *labeller;
    143 	const char *name;
    144 	const char *alias;
    145 	const char *orphan_vg_name;
    146 	uint32_t features;
    147 	void *library;
    148 	void *private;
    149 };
    150 
    151 struct pv_segment {
    152 	struct dm_list list;	/* Member of pv->segments: ordered list
    153 				 * covering entire data area on this PV */
    154 
    155 	struct physical_volume *pv;
    156 	uint32_t pe;
    157 	uint32_t len;
    158 
    159 	struct lv_segment *lvseg;	/* NULL if free space */
    160 	uint32_t lv_area;	/* Index to area in LV segment */
    161 };
    162 
    163 #define pvseg_is_allocated(pvseg) ((pvseg)->lvseg)
    164 
    165 struct physical_volume {
    166 	struct id id;
    167 	struct device *dev;
    168 	const struct format_type *fmt;
    169 	const char *vg_name;
    170 	struct id vgid;
    171 
    172 	uint32_t status;
    173 	uint64_t size;
    174 
    175 	/* physical extents */
    176 	uint32_t pe_size;
    177 	uint64_t pe_start;
    178 	uint32_t pe_count;
    179 	uint32_t pe_alloc_count;
    180 	unsigned long pe_align;
    181 
    182 	struct dm_list segments;	/* Ordered pv_segments covering complete PV */
    183 	struct dm_list tags;
    184 };
    185 
    186 struct format_instance {
    187 	const struct format_type *fmt;
    188 	struct dm_list metadata_areas;	/* e.g. metadata locations */
    189 	void *private;
    190 };
    191 
    192 struct volume_group {
    193 	struct cmd_context *cmd;
    194 	struct format_instance *fid;
    195 	uint32_t seqno;		/* Metadata sequence number */
    196 
    197 	struct id id;
    198 	char *name;
    199 	char *system_id;
    200 
    201 	uint32_t status;
    202 	alloc_policy_t alloc;
    203 
    204 	uint32_t extent_size;
    205 	uint32_t extent_count;
    206 	uint32_t free_count;
    207 
    208 	uint32_t max_lv;
    209 	uint32_t max_pv;
    210 
    211 	/* physical volumes */
    212 	uint32_t pv_count;
    213 	struct dm_list pvs;
    214 
    215 	/*
    216 	 * logical volumes
    217 	 * The following relationship should always hold:
    218 	 * dm_list_size(lvs) = lv_count + 2 * snapshot_count
    219 	 *
    220 	 * Snapshots consist of 2 instances of "struct logical_volume":
    221 	 * - cow (lv_name is visible to the user)
    222 	 * - snapshot (lv_name is 'snapshotN')
    223 	 * Neither of these instances is reflected in lv_count, but we
    224 	 * multiply the snapshot_count by 2.
    225 	 *
    226 	 * Mirrors consist of multiple instances of "struct logical_volume":
    227 	 * - one for the mirror log
    228 	 * - one for each mirror leg
    229 	 * - one for the user-visible mirror LV
    230 	 * all of the instances are reflected in lv_count.
    231 	 */
    232 	uint32_t lv_count;
    233 	uint32_t snapshot_count;
    234 	struct dm_list lvs;
    235 
    236 	struct dm_list tags;
    237 };
    238 
    239 /* There will be one area for each stripe */
    240 struct lv_segment_area {
    241 	area_type_t type;
    242 	union {
    243 		struct {
    244 			struct pv_segment *pvseg;
    245 		} pv;
    246 		struct {
    247 			struct logical_volume *lv;
    248 			uint32_t le;
    249 		} lv;
    250 	} u;
    251 };
    252 
    253 struct segment_type;
    254 struct lv_segment {
    255 	struct dm_list list;
    256 	struct logical_volume *lv;
    257 
    258 	const struct segment_type *segtype;
    259 	uint32_t le;
    260 	uint32_t len;
    261 
    262 	uint32_t status;
    263 
    264 	/* FIXME Fields depend on segment type */
    265 	uint32_t stripe_size;
    266 	uint32_t area_count;
    267 	uint32_t area_len;
    268 	struct logical_volume *origin;
    269 	struct logical_volume *cow;
    270 	struct dm_list origin_list;
    271 	uint32_t chunk_size;	/* For snapshots - in sectors */
    272 	uint32_t region_size;	/* For mirrors - in sectors */
    273 	uint32_t extents_copied;
    274 	struct logical_volume *log_lv;
    275 
    276 	struct dm_list tags;
    277 
    278 	struct lv_segment_area *areas;
    279 };
    280 
    281 #define seg_type(seg, s)	(seg)->areas[(s)].type
    282 #define seg_pv(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pv
    283 #define seg_lv(seg, s)		(seg)->areas[(s)].u.lv.lv
    284 
    285 struct logical_volume {
    286 	union lvid lvid;
    287 	char *name;
    288 
    289 	struct volume_group *vg;
    290 
    291 	uint32_t status;
    292 	alloc_policy_t alloc;
    293 	uint32_t read_ahead;
    294 	int32_t major;
    295 	int32_t minor;
    296 
    297 	uint64_t size;		/* Sectors */
    298 	uint32_t le_count;
    299 
    300 	uint32_t origin_count;
    301 	struct dm_list snapshot_segs;
    302 	struct lv_segment *snapshot;
    303 
    304 	struct dm_list segments;
    305 	struct dm_list tags;
    306 	struct dm_list segs_using_this_lv;
    307 };
    308 
    309 struct pe_range {
    310 	struct dm_list list;
    311 	uint32_t start;		/* PEs */
    312 	uint32_t count;		/* PEs */
    313 };
    314 
    315 struct pv_list {
    316 	struct dm_list list;
    317 	struct physical_volume *pv;
    318 	struct dm_list *mdas;	/* Metadata areas */
    319 	struct dm_list *pe_ranges;	/* Ranges of PEs e.g. for allocation */
    320 };
    321 
    322 struct lv_list {
    323 	struct dm_list list;
    324 	struct logical_volume *lv;
    325 };
    326 
    327 /*
    328 * Utility functions
    329 */
    330 int vg_write(struct volume_group *vg);
    331 int vg_commit(struct volume_group *vg);
    332 int vg_revert(struct volume_group *vg);
    333 struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name,
    334 			     const char *vgid, int *consistent);
    335 struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
    336 				struct dm_list *mdas, uint64_t *label_sector,
    337 				int warnings);
    338 struct dm_list *get_pvs(struct cmd_context *cmd);
    339 
    340 /* Set full_scan to 1 to re-read every (filtered) device label */
    341 struct dm_list *get_vgs(struct cmd_context *cmd, int full_scan);
    342 struct dm_list *get_vgids(struct cmd_context *cmd, int full_scan);
    343 int scan_vgs_for_pvs(struct cmd_context *cmd);
    344 
    345 int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
    346 	     struct dm_list *mdas, int64_t label_sector);
    347 int is_pv(pv_t *pv);
    348 int is_orphan_vg(const char *vg_name);
    349 int is_orphan(const pv_t *pv);
    350 int vgs_are_compatible(struct cmd_context *cmd,
    351 		       struct volume_group *vg_from,
    352 		       struct volume_group *vg_to);
    353 vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
    354 		       const char *vgid,
    355 		       uint32_t lock_flags, uint32_t status_flags,
    356 		       uint32_t misc_flags);
    357 
    358 /* pe_start and pe_end relate to any existing data so that new metadata
    359 * areas can avoid overlap */
    360 pv_t *pv_create(const struct cmd_context *cmd,
    361 		      struct device *dev,
    362 		      struct id *id,
    363 		      uint64_t size,
    364 		      uint64_t pe_start,
    365 		      uint32_t existing_extent_count,
    366 		      uint32_t existing_extent_size,
    367 		      int pvmetadatacopies,
    368 		      uint64_t pvmetadatasize, struct dm_list *mdas);
    369 int pv_resize(struct physical_volume *pv, struct volume_group *vg,
    370              uint32_t new_pe_count);
    371 int pv_analyze(struct cmd_context *cmd, const char *pv_name,
    372 	       uint64_t label_sector);
    373 
    374 /* FIXME: move internal to library */
    375 uint32_t pv_list_extents_free(const struct dm_list *pvh);
    376 
    377 struct volume_group *vg_create(struct cmd_context *cmd, const char *name,
    378 			       uint32_t extent_size, uint32_t max_pv,
    379 			       uint32_t max_lv, alloc_policy_t alloc,
    380 			       int pv_count, char **pv_names);
    381 int vg_remove(struct volume_group *vg);
    382 int vg_remove_single(struct cmd_context *cmd, const char *vg_name,
    383 		     struct volume_group *vg, int consistent,
    384 		     force_t force);
    385 int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
    386 	      const char *new_name);
    387 int vg_extend(struct volume_group *vg, int pv_count, char **pv_names);
    388 int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
    389 		     uint32_t new_extent_size);
    390 int vg_split_mdas(struct cmd_context *cmd, struct volume_group *vg_from,
    391 		  struct volume_group *vg_to);
    392 
    393 /* Manipulate LVs */
    394 struct logical_volume *lv_create_empty(const char *name,
    395 				       union lvid *lvid,
    396 				       uint32_t status,
    397 				       alloc_policy_t alloc,
    398 				       int import,
    399 				       struct volume_group *vg);
    400 
    401 /* Write out LV contents */
    402 int set_lv(struct cmd_context *cmd, struct logical_volume *lv,
    403            uint64_t sectors, int value);
    404 
    405 /* Reduce the size of an LV by extents */
    406 int lv_reduce(struct logical_volume *lv, uint32_t extents);
    407 
    408 /* Empty an LV prior to deleting it */
    409 int lv_empty(struct logical_volume *lv);
    410 
    411 /* Empty an LV and add error segment */
    412 int replace_lv_with_error_segment(struct logical_volume *lv);
    413 
    414 /* Entry point for all LV extent allocations */
    415 int lv_extend(struct logical_volume *lv,
    416 	      const struct segment_type *segtype,
    417 	      uint32_t stripes, uint32_t stripe_size,
    418 	      uint32_t mirrors, uint32_t extents,
    419 	      struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
    420 	      uint32_t status, struct dm_list *allocatable_pvs,
    421 	      alloc_policy_t alloc);
    422 
    423 /* lv must be part of lv->vg->lvs */
    424 int lv_remove(struct logical_volume *lv);
    425 
    426 int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
    427 		     force_t force);
    428 
    429 int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *lv,
    430 				force_t force);
    431 
    432 int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,
    433 	      const char *new_name);
    434 
    435 /*
    436  * Functions for layer manipulation
    437  */
    438 int insert_layer_for_segments_on_pv(struct cmd_context *cmd,
    439 				    struct logical_volume *lv_where,
    440 				    struct logical_volume *layer_lv,
    441 				    uint32_t status,
    442 				    struct pv_list *pv,
    443 				    struct dm_list *lvs_changed);
    444 int remove_layers_for_segments(struct cmd_context *cmd,
    445 			       struct logical_volume *lv,
    446 			       struct logical_volume *layer_lv,
    447 			       uint32_t status_mask, struct dm_list *lvs_changed);
    448 int remove_layers_for_segments_all(struct cmd_context *cmd,
    449 				   struct logical_volume *layer_lv,
    450 				   uint32_t status_mask,
    451 				   struct dm_list *lvs_changed);
    452 int split_parent_segments_for_layer(struct cmd_context *cmd,
    453 				    struct logical_volume *layer_lv);
    454 int remove_layer_from_lv(struct logical_volume *lv,
    455 			 struct logical_volume *layer_lv);
    456 struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
    457 					   struct logical_volume *lv_where,
    458 					   uint32_t status,
    459 					   const char *layer_suffix);
    460 
    461 /* Find a PV within a given VG */
    462 struct pv_list *find_pv_in_vg(const struct volume_group *vg,
    463 			      const char *pv_name);
    464 pv_t *find_pv_in_vg_by_uuid(const struct volume_group *vg,
    465 			    const struct id *id);
    466 
    467 /* Find an LV within a given VG */
    468 struct lv_list *find_lv_in_vg(const struct volume_group *vg,
    469 			      const char *lv_name);
    470 
    471 /* FIXME Merge these functions with ones above */
    472 struct logical_volume *find_lv(const struct volume_group *vg,
    473 			       const char *lv_name);
    474 struct physical_volume *find_pv_by_name(struct cmd_context *cmd,
    475 					const char *pv_name);
    476 
    477 /* Find LV segment containing given LE */
    478 struct lv_segment *first_seg(const struct logical_volume *lv);
    479 
    480 
    481 /*
    482 * Useful functions for managing snapshots.
    483 */
    484 int lv_is_origin(const struct logical_volume *lv);
    485 int lv_is_cow(const struct logical_volume *lv);
    486 int lv_is_visible(const struct logical_volume *lv);
    487 
    488 /* Test if given LV is visible from user's perspective */
    489 int lv_is_displayable(const struct logical_volume *lv);
    490 
    491 int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv);
    492 
    493 /* Given a cow LV, return return the snapshot lv_segment that uses it */
    494 struct lv_segment *find_cow(const struct logical_volume *lv);
    495 
    496 /* Given a cow LV, return its origin */
    497 struct logical_volume *origin_from_cow(const struct logical_volume *lv);
    498 
    499 int vg_add_snapshot(const char *name,
    500 		    struct logical_volume *origin, struct logical_volume *cow,
    501 		    union lvid *lvid, uint32_t extent_count,
    502 		    uint32_t chunk_size);
    503 
    504 int vg_remove_snapshot(struct logical_volume *cow);
    505 
    506 int vg_check_status(const struct volume_group *vg, uint32_t status);
    507 
    508 /*
    509 * Mirroring functions
    510 */
    511 struct lv_segment *find_mirror_seg(struct lv_segment *seg);
    512 int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
    513 		   uint32_t mirrors, uint32_t stripes,
    514 		   uint32_t region_size, uint32_t log_count,
    515 		   struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags);
    516 int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
    517 		      uint32_t mirrors, uint32_t log_count,
    518 		      struct dm_list *pvs, uint32_t status_mask);
    519 
    520 int is_temporary_mirror_layer(const struct logical_volume *lv);
    521 struct logical_volume * find_temporary_mirror(const struct logical_volume *lv);
    522 uint32_t lv_mirror_count(const struct logical_volume *lv);
    523 uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
    524                                     uint32_t region_size);
    525 int remove_mirrors_from_segments(struct logical_volume *lv,
    526 				 uint32_t new_mirrors, uint32_t status_mask);
    527 int add_mirrors_to_segments(struct cmd_context *cmd, struct logical_volume *lv,
    528 			    uint32_t mirrors, uint32_t region_size,
    529 			    struct dm_list *allocatable_pvs, alloc_policy_t alloc);
    530 
    531 int remove_mirror_images(struct logical_volume *lv, uint32_t num_mirrors,
    532 			 struct dm_list *removable_pvs, unsigned remove_log);
    533 int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
    534 		      uint32_t mirrors, uint32_t stripes, uint32_t region_size,
    535 		      struct dm_list *allocatable_pvs, alloc_policy_t alloc,
    536 		      uint32_t log_count);
    537 struct logical_volume *detach_mirror_log(struct lv_segment *seg);
    538 int attach_mirror_log(struct lv_segment *seg, struct logical_volume *lv);
    539 int remove_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
    540 		      struct dm_list *removable_pvs);
    541 int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
    542 		   uint32_t log_count, uint32_t region_size,
    543 		   struct dm_list *allocatable_pvs, alloc_policy_t alloc);
    544 
    545 int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
    546 			      struct dm_list *removable_pvs, unsigned remove_log);
    547 int collapse_mirrored_lv(struct logical_volume *lv);
    548 int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage);
    549 
    550 struct logical_volume *find_pvmove_lv(struct volume_group *vg,
    551 				      struct device *dev, uint32_t lv_type);
    552 struct logical_volume *find_pvmove_lv_from_pvname(struct cmd_context *cmd,
    553 						  struct volume_group *vg,
    554 						  const char *name,
    555 						  uint32_t lv_type);
    556 const char *get_pvmove_pvname_from_lv(struct logical_volume *lv);
    557 const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr);
    558 float copy_percent(struct logical_volume *lv_mirr);
    559 struct dm_list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
    560 			  struct logical_volume *lv);
    561 
    562 uint32_t find_free_lvnum(struct logical_volume *lv);
    563 char *generate_lv_name(struct volume_group *vg, const char *format,
    564 		       char *buffer, size_t len);
    565 
    566 /*
    567 * Begin skeleton for external LVM library
    568 */
    569 struct device *pv_dev(const pv_t *pv);
    570 const char *pv_vg_name(const pv_t *pv);
    571 const char *pv_dev_name(const pv_t *pv);
    572 uint64_t pv_size(const pv_t *pv);
    573 uint32_t pv_status(const pv_t *pv);
    574 uint32_t pv_pe_size(const pv_t *pv);
    575 uint64_t pv_pe_start(const pv_t *pv);
    576 uint32_t pv_pe_count(const pv_t *pv);
    577 uint32_t pv_pe_alloc_count(const pv_t *pv);
    578 
    579 int vg_missing_pv_count(const vg_t *vg);
    580 uint32_t vg_status(const vg_t *vg);
    581 #define vg_is_clustered(vg) (vg_status((vg)) & CLUSTERED)
    582 
    583 struct vgcreate_params {
    584 	char *vg_name;
    585 	uint32_t extent_size;
    586 	size_t max_pv;
    587 	size_t max_lv;
    588 	alloc_policy_t alloc;
    589 	int clustered; /* FIXME: put this into a 'status' variable instead? */
    590 };
    591 
    592 int validate_vg_create_params(struct cmd_context *cmd,
    593 			      struct vgcreate_params *vp);
    594 
    595 int validate_vg_rename_params(struct cmd_context *cmd,
    596 			      const char *vg_name_old,
    597 			      const char *vg_name_new);
    598 #endif
    599