Home | History | Annotate | Line # | Download | only in include
metadata-exported.h revision 1.1.1.3
      1 /*	$NetBSD: metadata-exported.h,v 1.1.1.3 2009/12/02 00:25:43 haad Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
      5  * Copyright (C) 2004-2009 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 #define MAX_STRIPES 128U
     29 #define SECTOR_SHIFT 9L
     30 #define STRIPE_SIZE_MIN ( (unsigned) lvm_getpagesize() >> SECTOR_SHIFT)	/* PAGESIZE in sectors */
     31 #define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT)	/* 512 KB in sectors */
     32 #define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
     33 #define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT)	/* 512 KB in sectors */
     34 #define MAX_RESTRICTED_LVS 255	/* Used by FMT_RESTRICTED_LVIDS */
     35 
     36 /* Layer suffix */
     37 #define MIRROR_SYNC_LAYER "_mimagetmp"
     38 
     39 /* Various flags */
     40 /* Note that the bits no longer necessarily correspond to LVM1 disk format */
     41 
     42 #define PARTIAL_VG		0x00000001U	/* VG */
     43 #define EXPORTED_VG          	0x00000002U	/* VG PV */
     44 #define RESIZEABLE_VG        	0x00000004U	/* VG */
     45 
     46 /* May any free extents on this PV be used or must they be left free? */
     47 #define ALLOCATABLE_PV         	0x00000008U	/* PV */
     48 
     49 //#define SPINDOWN_LV          	0x00000010U	/* LV */
     50 //#define BADBLOCK_ON       	0x00000020U	/* LV */
     51 #define VISIBLE_LV		0x00000040U	/* LV */
     52 #define FIXED_MINOR		0x00000080U	/* LV */
     53 /* FIXME Remove when metadata restructuring is completed */
     54 #define SNAPSHOT		0x00001000U	/* LV - internal use only */
     55 #define PVMOVE			0x00002000U	/* VG LV SEG */
     56 #define LOCKED			0x00004000U	/* LV */
     57 #define MIRRORED		0x00008000U	/* LV - internal use only */
     58 //#define VIRTUAL			0x00010000U	/* LV - internal use only */
     59 #define MIRROR_LOG		0x00020000U	/* LV */
     60 #define MIRROR_IMAGE		0x00040000U	/* LV */
     61 #define MIRROR_NOTSYNCED	0x00080000U	/* LV */
     62 //#define ACTIVATE_EXCL		0x00100000U	/* LV - internal use only */
     63 //#define PRECOMMITTED		0x00200000U	/* VG - internal use only */
     64 #define CONVERTING		0x00400000U	/* LV */
     65 
     66 #define MISSING_PV              0x00800000U	/* PV */
     67 #define PARTIAL_LV              0x01000000U	/* LV - derived flag, not
     68 						   written out in metadata*/
     69 
     70 //#define POSTORDER_FLAG	0x02000000U /* Not real flags, reserved for
     71 //#define POSTORDER_OPEN_FLAG	0x04000000U    temporary use inside vg_read_internal. */
     72 //#define VIRTUAL_ORIGIN	0x08000000U	/* LV - internal use only */
     73 
     74 #define LVM_READ              	0x00000100U	/* LV VG */
     75 #define LVM_WRITE             	0x00000200U	/* LV VG */
     76 #define CLUSTERED         	0x00000400U	/* VG */
     77 //#define SHARED            	0x00000800U	/* VG */
     78 
     79 /* Format features flags */
     80 #define FMT_SEGMENTS		0x00000001U	/* Arbitrary segment params? */
     81 #define FMT_MDAS		0x00000002U	/* Proper metadata areas? */
     82 #define FMT_TAGS		0x00000004U	/* Tagging? */
     83 #define FMT_UNLIMITED_VOLS	0x00000008U	/* Unlimited PVs/LVs? */
     84 #define FMT_RESTRICTED_LVIDS	0x00000010U	/* LVID <= 255 */
     85 #define FMT_ORPHAN_ALLOCATABLE	0x00000020U	/* Orphan PV allocatable? */
     86 //#define FMT_PRECOMMIT		0x00000040U	/* Supports pre-commit? */
     87 #define FMT_RESIZE_PV		0x00000080U	/* Supports pvresize? */
     88 #define FMT_UNLIMITED_STRIPESIZE 0x00000100U	/* Unlimited stripe size? */
     89 #define FMT_RESTRICTED_READAHEAD 0x00000200U	/* Readahead restricted to 2-120? */
     90 
     91 /* Mirror conversion type flags */
     92 #define MIRROR_BY_SEG		0x00000001U	/* segment-by-segment mirror */
     93 #define MIRROR_BY_LV		0x00000002U	/* mirror using whole mimage LVs */
     94 #define MIRROR_SKIP_INIT_SYNC	0x00000010U	/* skip initial sync */
     95 
     96 /* vg_read and vg_read_for_update flags */
     97 #define READ_ALLOW_INCONSISTENT	0x00010000U
     98 #define READ_ALLOW_EXPORTED	0x00020000U
     99 #define READ_WITHOUT_LOCK       0x00040000U
    100 
    101 /* A meta-flag, useful with toollib for_each_* functions. */
    102 #define READ_FOR_UPDATE 	0x00100000U
    103 
    104 /* vg's "read_status" field */
    105 #define FAILED_INCONSISTENT	0x00000001U
    106 #define FAILED_LOCKING		0x00000002U
    107 #define FAILED_NOTFOUND		0x00000004U
    108 #define FAILED_READ_ONLY	0x00000008U
    109 #define FAILED_EXPORTED		0x00000010U
    110 #define FAILED_RESIZEABLE	0x00000020U
    111 #define FAILED_CLUSTERED	0x00000040U
    112 #define FAILED_ALLOCATION	0x00000080U
    113 #define FAILED_EXIST		0x00000100U
    114 #define SUCCESS			0x00000000U
    115 
    116 /* Ordered list - see lv_manip.c */
    117 typedef enum {
    118 	ALLOC_INVALID,
    119 	ALLOC_CONTIGUOUS,
    120 	ALLOC_CLING,
    121 	ALLOC_NORMAL,
    122 	ALLOC_ANYWHERE,
    123 	ALLOC_INHERIT
    124 } alloc_policy_t;
    125 
    126 typedef enum {
    127 	AREA_UNASSIGNED,
    128 	AREA_PV,
    129 	AREA_LV
    130 } area_type_t;
    131 
    132 /*
    133  * Whether or not to force an operation.
    134  */
    135 typedef enum {
    136 	PROMPT = 0, /* Issue yes/no prompt to confirm operation */
    137 	DONT_PROMPT = 1, /* Skip yes/no prompt */
    138 	DONT_PROMPT_OVERRIDE = 2 /* Skip prompt + override a second condition */
    139 } force_t;
    140 
    141 typedef enum {
    142 	PERCENT_0 = 0,
    143 	PERCENT_0_TO_100 = 1,
    144 	PERCENT_100 = 2,
    145 	PERCENT_INVALID = 3
    146 } percent_range_t;
    147 
    148 struct cmd_context;
    149 struct format_handler;
    150 struct labeller;
    151 
    152 struct format_type {
    153 	struct dm_list list;
    154 	struct cmd_context *cmd;
    155 	struct format_handler *ops;
    156 	struct labeller *labeller;
    157 	const char *name;
    158 	const char *alias;
    159 	const char *orphan_vg_name;
    160 	uint32_t features;
    161 	void *library;
    162 	void *private;
    163 };
    164 
    165 struct pv_segment {
    166 	struct dm_list list;	/* Member of pv->segments: ordered list
    167 				 * covering entire data area on this PV */
    168 
    169 	struct physical_volume *pv;
    170 	uint32_t pe;
    171 	uint32_t len;
    172 
    173 	struct lv_segment *lvseg;	/* NULL if free space */
    174 	uint32_t lv_area;	/* Index to area in LV segment */
    175 };
    176 
    177 #define pvseg_is_allocated(pvseg) ((pvseg)->lvseg)
    178 
    179 struct physical_volume {
    180 	struct id id;
    181 	struct device *dev;
    182 	const struct format_type *fmt;
    183 	const char *vg_name;
    184 	struct id vgid;
    185 
    186 	uint32_t status;
    187 	uint64_t size;
    188 
    189 	/* physical extents */
    190 	uint32_t pe_size;
    191 	uint64_t pe_start;
    192 	uint32_t pe_count;
    193 	uint32_t pe_alloc_count;
    194 	unsigned long pe_align;
    195 	unsigned long pe_align_offset;
    196 
    197 	struct dm_list segments;	/* Ordered pv_segments covering complete PV */
    198 	struct dm_list tags;
    199 };
    200 
    201 struct format_instance {
    202 	const struct format_type *fmt;
    203 	struct dm_list metadata_areas;	/* e.g. metadata locations */
    204 	void *private;
    205 };
    206 
    207 struct volume_group {
    208 	struct cmd_context *cmd;
    209 	struct dm_pool *vgmem;
    210 	struct format_instance *fid;
    211 	uint32_t seqno;		/* Metadata sequence number */
    212 
    213 	struct id id;
    214 	char *name;
    215 	char *system_id;
    216 
    217 	uint32_t status;
    218 	alloc_policy_t alloc;
    219 
    220 	uint32_t extent_size;
    221 	uint32_t extent_count;
    222 	uint32_t free_count;
    223 
    224 	uint32_t max_lv;
    225 	uint32_t max_pv;
    226 
    227 	/* physical volumes */
    228 	uint32_t pv_count;
    229 	struct dm_list pvs;
    230 
    231 	/*
    232 	 * logical volumes
    233 	 * The following relationship should always hold:
    234 	 * dm_list_size(lvs) = user visible lv_count + snapshot_count + other invisible LVs
    235 	 *
    236 	 * Snapshots consist of 2 instances of "struct logical_volume":
    237 	 * - cow (lv_name is visible to the user)
    238 	 * - snapshot (lv_name is 'snapshotN')
    239 	 *
    240 	 * Mirrors consist of multiple instances of "struct logical_volume":
    241 	 * - one for the mirror log
    242 	 * - one for each mirror leg
    243 	 * - one for the user-visible mirror LV
    244 	 */
    245 	struct dm_list lvs;
    246 
    247 	struct dm_list tags;
    248 
    249 	/*
    250 	 * FIXME: Move the next fields into a different struct?
    251 	 */
    252 
    253 	/*
    254 	 * List of removed physical volumes by pvreduce.
    255 	 * They have to get cleared on vg_commit.
    256 	 */
    257 	struct dm_list removed_pvs;
    258 	uint32_t open_mode; /* FIXME: read or write - check lock type? */
    259 
    260 	/*
    261 	 * Store result of the last vg_read().
    262 	 * 0 for success else appropriate FAILURE_* bits set.
    263 	 */
    264 	uint32_t read_status;
    265 };
    266 
    267 /* There will be one area for each stripe */
    268 struct lv_segment_area {
    269 	area_type_t type;
    270 	union {
    271 		struct {
    272 			struct pv_segment *pvseg;
    273 		} pv;
    274 		struct {
    275 			struct logical_volume *lv;
    276 			uint32_t le;
    277 		} lv;
    278 	} u;
    279 };
    280 
    281 struct segment_type;
    282 struct lv_segment {
    283 	struct dm_list list;
    284 	struct logical_volume *lv;
    285 
    286 	const struct segment_type *segtype;
    287 	uint32_t le;
    288 	uint32_t len;
    289 
    290 	uint32_t status;
    291 
    292 	/* FIXME Fields depend on segment type */
    293 	uint32_t stripe_size;
    294 	uint32_t area_count;
    295 	uint32_t area_len;
    296 	struct logical_volume *origin;
    297 	struct logical_volume *cow;
    298 	struct dm_list origin_list;
    299 	uint32_t chunk_size;	/* For snapshots - in sectors */
    300 	uint32_t region_size;	/* For mirrors - in sectors */
    301 	uint32_t extents_copied;
    302 	struct logical_volume *log_lv;
    303 	void *segtype_private;
    304 
    305 	struct dm_list tags;
    306 
    307 	struct lv_segment_area *areas;
    308 };
    309 
    310 #define seg_type(seg, s)	(seg)->areas[(s)].type
    311 #define seg_pv(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pv
    312 #define seg_lv(seg, s)		(seg)->areas[(s)].u.lv.lv
    313 
    314 struct logical_volume {
    315 	union lvid lvid;
    316 	char *name;
    317 
    318 	struct volume_group *vg;
    319 
    320 	uint32_t status;
    321 	alloc_policy_t alloc;
    322 	uint32_t read_ahead;
    323 	int32_t major;
    324 	int32_t minor;
    325 
    326 	uint64_t size;		/* Sectors */
    327 	uint32_t le_count;
    328 
    329 	uint32_t origin_count;
    330 	struct dm_list snapshot_segs;
    331 	struct lv_segment *snapshot;
    332 
    333 	struct dm_list segments;
    334 	struct dm_list tags;
    335 	struct dm_list segs_using_this_lv;
    336 };
    337 
    338 struct pe_range {
    339 	struct dm_list list;
    340 	uint32_t start;		/* PEs */
    341 	uint32_t count;		/* PEs */
    342 };
    343 
    344 struct pv_list {
    345 	struct dm_list list;
    346 	struct physical_volume *pv;
    347 	struct dm_list *mdas;	/* Metadata areas */
    348 	struct dm_list *pe_ranges;	/* Ranges of PEs e.g. for allocation */
    349 };
    350 
    351 struct lv_list {
    352 	struct dm_list list;
    353 	struct logical_volume *lv;
    354 };
    355 
    356 struct pvcreate_params {
    357 	int zero;
    358 	uint64_t size;
    359 	uint64_t data_alignment;
    360 	uint64_t data_alignment_offset;
    361 	int pvmetadatacopies;
    362 	uint64_t pvmetadatasize;
    363 	int64_t labelsector;
    364 	struct id id; /* FIXME: redundant */
    365 	struct id *idp; /* 0 if no --uuid option */
    366 	uint64_t pe_start;
    367 	uint32_t extent_count;
    368 	uint32_t extent_size;
    369 	const char *restorefile; /* 0 if no --restorefile option */
    370 	force_t force;
    371 	unsigned yes;
    372 };
    373 
    374 struct physical_volume *pvcreate_single(struct cmd_context *cmd,
    375 					const char *pv_name,
    376 					struct pvcreate_params *pp);
    377 void pvcreate_params_set_defaults(struct pvcreate_params *pp);
    378 
    379 /*
    380 * Utility functions
    381 */
    382 int vg_write(struct volume_group *vg);
    383 int vg_commit(struct volume_group *vg);
    384 int vg_revert(struct volume_group *vg);
    385 struct volume_group *vg_read_internal(struct cmd_context *cmd, const char *vg_name,
    386 			     const char *vgid, int *consistent);
    387 struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
    388 				struct dm_list *mdas, uint64_t *label_sector,
    389 				int warnings, int scan_label_only);
    390 struct dm_list *get_pvs(struct cmd_context *cmd);
    391 
    392 /*
    393  * Add/remove LV to/from volume group
    394  */
    395 int link_lv_to_vg(struct volume_group *vg, struct logical_volume *lv);
    396 int unlink_lv_from_vg(struct logical_volume *lv);
    397 void lv_set_visible(struct logical_volume *lv);
    398 void lv_set_hidden(struct logical_volume *lv);
    399 
    400 /* Set full_scan to 1 to re-read every (filtered) device label */
    401 struct dm_list *get_vgnames(struct cmd_context *cmd, int full_scan);
    402 struct dm_list *get_vgids(struct cmd_context *cmd, int full_scan);
    403 int scan_vgs_for_pvs(struct cmd_context *cmd);
    404 
    405 int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
    406 	     struct dm_list *mdas, int64_t label_sector);
    407 int is_pv(struct physical_volume *pv);
    408 int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
    409 	    const char *pv_name);
    410 int move_pvs_used_by_lv(struct volume_group *vg_from,
    411 			struct volume_group *vg_to,
    412 			const char *lv_name);
    413 int is_orphan_vg(const char *vg_name);
    414 int is_orphan(const struct physical_volume *pv);
    415 int vgs_are_compatible(struct cmd_context *cmd,
    416 		       struct volume_group *vg_from,
    417 		       struct volume_group *vg_to);
    418 uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname);
    419 
    420 /*
    421  * Return a handle to VG metadata.
    422  */
    423 struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name,
    424               const char *vgid, uint32_t flags);
    425 struct volume_group *vg_read_for_update(struct cmd_context *cmd, const char *vg_name,
    426                          const char *vgid, uint32_t flags);
    427 
    428 /*
    429  * Test validity of a VG handle.
    430  */
    431 uint32_t vg_read_error(struct volume_group *vg_handle);
    432 
    433 /* pe_start and pe_end relate to any existing data so that new metadata
    434 * areas can avoid overlap */
    435 struct physical_volume *pv_create(const struct cmd_context *cmd,
    436 		      struct device *dev,
    437 		      struct id *id,
    438 		      uint64_t size,
    439 		      unsigned long data_alignment,
    440 		      unsigned long data_alignment_offset,
    441 		      uint64_t pe_start,
    442 		      uint32_t existing_extent_count,
    443 		      uint32_t existing_extent_size,
    444 		      int pvmetadatacopies,
    445 		      uint64_t pvmetadatasize, struct dm_list *mdas);
    446 int pv_resize(struct physical_volume *pv, struct volume_group *vg,
    447              uint32_t new_pe_count);
    448 int pv_analyze(struct cmd_context *cmd, const char *pv_name,
    449 	       uint64_t label_sector);
    450 
    451 /* FIXME: move internal to library */
    452 uint32_t pv_list_extents_free(const struct dm_list *pvh);
    453 
    454 struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name);
    455 int vg_remove_mdas(struct volume_group *vg);
    456 int vg_remove_check(struct volume_group *vg);
    457 int vg_remove(struct volume_group *vg);
    458 int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
    459 	      const char *new_name);
    460 int vg_extend(struct volume_group *vg, int pv_count, char **pv_names,
    461 	      struct pvcreate_params *pp);
    462 int vg_reduce(struct volume_group *vg, char *pv_name);
    463 int vg_set_extent_size(struct volume_group *vg, uint32_t new_extent_size);
    464 int vg_set_max_lv(struct volume_group *vg, uint32_t max_lv);
    465 int vg_set_max_pv(struct volume_group *vg, uint32_t max_pv);
    466 int vg_set_alloc_policy(struct volume_group *vg, alloc_policy_t alloc);
    467 int vg_set_clustered(struct volume_group *vg, int clustered);
    468 int vg_split_mdas(struct cmd_context *cmd, struct volume_group *vg_from,
    469 		  struct volume_group *vg_to);
    470 
    471 /* FIXME: refactor / unexport when lvremove liblvm refactoring dones */
    472 int remove_lvs_in_vg(struct cmd_context *cmd,
    473 		     struct volume_group *vg,
    474 		     force_t force);
    475 /*
    476  * vg_release() must be called on every struct volume_group allocated
    477  * by vg_create() or vg_read_internal() to free it when no longer required.
    478  */
    479 void vg_release(struct volume_group *vg);
    480 
    481 /* Manipulate LVs */
    482 struct logical_volume *lv_create_empty(const char *name,
    483 				       union lvid *lvid,
    484 				       uint32_t status,
    485 				       alloc_policy_t alloc,
    486 				       struct volume_group *vg);
    487 
    488 /* Write out LV contents */
    489 int set_lv(struct cmd_context *cmd, struct logical_volume *lv,
    490            uint64_t sectors, int value);
    491 
    492 /* Reduce the size of an LV by extents */
    493 int lv_reduce(struct logical_volume *lv, uint32_t extents);
    494 
    495 /* Empty an LV prior to deleting it */
    496 int lv_empty(struct logical_volume *lv);
    497 
    498 /* Empty an LV and add error segment */
    499 int replace_lv_with_error_segment(struct logical_volume *lv);
    500 
    501 /* Entry point for all LV extent allocations */
    502 int lv_extend(struct logical_volume *lv,
    503 	      const struct segment_type *segtype,
    504 	      uint32_t stripes, uint32_t stripe_size,
    505 	      uint32_t mirrors, uint32_t extents,
    506 	      struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
    507 	      uint32_t status, struct dm_list *allocatable_pvs,
    508 	      alloc_policy_t alloc);
    509 
    510 /* lv must be part of lv->vg->lvs */
    511 int lv_remove(struct logical_volume *lv);
    512 
    513 int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
    514 		     force_t force);
    515 
    516 int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *lv,
    517 				force_t force);
    518 
    519 int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,
    520 	      const char *new_name);
    521 
    522 uint64_t extents_from_size(struct cmd_context *cmd, uint64_t size,
    523 			   uint32_t extent_size);
    524 
    525 /* FIXME: refactor and reduce the size of this struct! */
    526 struct lvcreate_params {
    527 	/* flags */
    528 	int snapshot; /* snap */
    529 	int zero; /* all */
    530 	int major; /* all */
    531 	int minor; /* all */
    532 	int corelog; /* mirror */
    533 	int nosync; /* mirror */
    534 
    535 	char *origin; /* snap */
    536 	const char *vg_name; /* all */
    537 	const char *lv_name; /* all */
    538 
    539 	uint32_t stripes; /* striped */
    540 	uint32_t stripe_size; /* striped */
    541 	uint32_t chunk_size; /* snapshot */
    542 	uint32_t region_size; /* mirror */
    543 
    544 	uint32_t mirrors; /* mirror */
    545 
    546 	const struct segment_type *segtype; /* all */
    547 
    548 	/* size */
    549 	uint32_t extents; /* all */
    550 	uint32_t voriginextents; /* snapshot */
    551 	uint64_t voriginsize; /* snapshot */
    552 	struct dm_list *pvh; /* all */
    553 
    554 	uint32_t permission; /* all */
    555 	uint32_t read_ahead; /* all */
    556 	alloc_policy_t alloc; /* all */
    557 
    558 	const char *tag; /* all */
    559 };
    560 
    561 int lv_create_single(struct volume_group *vg,
    562 		     struct lvcreate_params *lp);
    563 
    564 /*
    565  * Functions for layer manipulation
    566  */
    567 int insert_layer_for_segments_on_pv(struct cmd_context *cmd,
    568 				    struct logical_volume *lv_where,
    569 				    struct logical_volume *layer_lv,
    570 				    uint32_t status,
    571 				    struct pv_list *pv,
    572 				    struct dm_list *lvs_changed);
    573 int remove_layers_for_segments(struct cmd_context *cmd,
    574 			       struct logical_volume *lv,
    575 			       struct logical_volume *layer_lv,
    576 			       uint32_t status_mask, struct dm_list *lvs_changed);
    577 int remove_layers_for_segments_all(struct cmd_context *cmd,
    578 				   struct logical_volume *layer_lv,
    579 				   uint32_t status_mask,
    580 				   struct dm_list *lvs_changed);
    581 int split_parent_segments_for_layer(struct cmd_context *cmd,
    582 				    struct logical_volume *layer_lv);
    583 int remove_layer_from_lv(struct logical_volume *lv,
    584 			 struct logical_volume *layer_lv);
    585 struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
    586 					   struct logical_volume *lv_where,
    587 					   uint32_t status,
    588 					   const char *layer_suffix);
    589 
    590 /* Find a PV within a given VG */
    591 struct pv_list *find_pv_in_vg(const struct volume_group *vg,
    592 			      const char *pv_name);
    593 struct physical_volume *find_pv_in_vg_by_uuid(const struct volume_group *vg,
    594 			    const struct id *id);
    595 
    596 /* Find an LV within a given VG */
    597 struct lv_list *find_lv_in_vg(const struct volume_group *vg,
    598 			      const char *lv_name);
    599 
    600 /* FIXME Merge these functions with ones above */
    601 struct logical_volume *find_lv(const struct volume_group *vg,
    602 			       const char *lv_name);
    603 struct physical_volume *find_pv_by_name(struct cmd_context *cmd,
    604 					const char *pv_name);
    605 
    606 /* Find LV segment containing given LE */
    607 struct lv_segment *first_seg(const struct logical_volume *lv);
    608 
    609 
    610 /*
    611 * Useful functions for managing snapshots.
    612 */
    613 int lv_is_origin(const struct logical_volume *lv);
    614 int lv_is_virtual_origin(const struct logical_volume *lv);
    615 int lv_is_cow(const struct logical_volume *lv);
    616 
    617 /* Test if given LV is visible from user's perspective */
    618 int lv_is_visible(const struct logical_volume *lv);
    619 
    620 int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv);
    621 
    622 /* Given a cow LV, return return the snapshot lv_segment that uses it */
    623 struct lv_segment *find_cow(const struct logical_volume *lv);
    624 
    625 /* Given a cow LV, return its origin */
    626 struct logical_volume *origin_from_cow(const struct logical_volume *lv);
    627 
    628 void init_snapshot_seg(struct lv_segment *seg, struct logical_volume *origin,
    629 		       struct logical_volume *cow, uint32_t chunk_size);
    630 
    631 int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow,
    632 		    union lvid *lvid, uint32_t extent_count,
    633 		    uint32_t chunk_size);
    634 
    635 int vg_remove_snapshot(struct logical_volume *cow);
    636 
    637 int vg_check_status(const struct volume_group *vg, uint32_t status);
    638 
    639 /*
    640  * Returns visible LV count - number of LVs from user perspective
    641  */
    642 unsigned vg_visible_lvs(const struct volume_group *vg);
    643 
    644 /*
    645  * Check if the VG reached maximal LVs count (if set)
    646  */
    647 int vg_max_lv_reached(struct volume_group *vg);
    648 
    649 /*
    650 * Mirroring functions
    651 */
    652 struct lv_segment *find_mirror_seg(struct lv_segment *seg);
    653 int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
    654 		   uint32_t mirrors, uint32_t stripes,
    655 		   uint32_t region_size, uint32_t log_count,
    656 		   struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags);
    657 int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
    658 		      uint32_t mirrors, uint32_t log_count,
    659 		      struct dm_list *pvs, uint32_t status_mask);
    660 
    661 int is_temporary_mirror_layer(const struct logical_volume *lv);
    662 struct logical_volume * find_temporary_mirror(const struct logical_volume *lv);
    663 uint32_t lv_mirror_count(const struct logical_volume *lv);
    664 uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
    665                                     uint32_t region_size);
    666 int remove_mirrors_from_segments(struct logical_volume *lv,
    667 				 uint32_t new_mirrors, uint32_t status_mask);
    668 int add_mirrors_to_segments(struct cmd_context *cmd, struct logical_volume *lv,
    669 			    uint32_t mirrors, uint32_t region_size,
    670 			    struct dm_list *allocatable_pvs, alloc_policy_t alloc);
    671 
    672 int remove_mirror_images(struct logical_volume *lv, uint32_t num_mirrors,
    673 			 struct dm_list *removable_pvs, unsigned remove_log);
    674 int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
    675 		      uint32_t mirrors, uint32_t stripes, uint32_t region_size,
    676 		      struct dm_list *allocatable_pvs, alloc_policy_t alloc,
    677 		      uint32_t log_count);
    678 struct logical_volume *detach_mirror_log(struct lv_segment *seg);
    679 int attach_mirror_log(struct lv_segment *seg, struct logical_volume *lv);
    680 int remove_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
    681 		      struct dm_list *removable_pvs);
    682 int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
    683 		   uint32_t log_count, uint32_t region_size,
    684 		   struct dm_list *allocatable_pvs, alloc_policy_t alloc);
    685 
    686 int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
    687 			      struct dm_list *removable_pvs, unsigned remove_log);
    688 int collapse_mirrored_lv(struct logical_volume *lv);
    689 int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage);
    690 
    691 struct logical_volume *find_pvmove_lv(struct volume_group *vg,
    692 				      struct device *dev, uint32_t lv_type);
    693 struct logical_volume *find_pvmove_lv_from_pvname(struct cmd_context *cmd,
    694 						  struct volume_group *vg,
    695 						  const char *name,
    696 						  const char *uuid,
    697 						  uint32_t lv_type);
    698 const char *get_pvmove_pvname_from_lv(struct logical_volume *lv);
    699 const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr);
    700 float copy_percent(struct logical_volume *lv_mirr,
    701 		   percent_range_t *percent_range);
    702 struct dm_list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
    703 			  struct logical_volume *lv);
    704 
    705 uint32_t find_free_lvnum(struct logical_volume *lv);
    706 char *generate_lv_name(struct volume_group *vg, const char *format,
    707 		       char *buffer, size_t len);
    708 
    709 /*
    710 * Begin skeleton for external LVM library
    711 */
    712 struct device *pv_dev(const struct physical_volume *pv);
    713 const char *pv_vg_name(const struct physical_volume *pv);
    714 const char *pv_dev_name(const struct physical_volume *pv);
    715 uint64_t pv_size(const struct physical_volume *pv);
    716 uint32_t pv_status(const struct physical_volume *pv);
    717 uint32_t pv_pe_size(const struct physical_volume *pv);
    718 uint64_t pv_pe_start(const struct physical_volume *pv);
    719 uint32_t pv_pe_count(const struct physical_volume *pv);
    720 uint32_t pv_pe_alloc_count(const struct physical_volume *pv);
    721 uint32_t pv_mda_count(const struct physical_volume *pv);
    722 
    723 uint64_t lv_size(const struct logical_volume *lv);
    724 
    725 int vg_missing_pv_count(const struct volume_group *vg);
    726 uint32_t vg_seqno(const struct volume_group *vg);
    727 uint32_t vg_status(const struct volume_group *vg);
    728 uint64_t vg_size(const struct volume_group *vg);
    729 uint64_t vg_free(const struct volume_group *vg);
    730 uint64_t vg_extent_size(const struct volume_group *vg);
    731 uint64_t vg_extent_count(const struct volume_group *vg);
    732 uint64_t vg_free_count(const struct volume_group *vg);
    733 uint64_t vg_pv_count(const struct volume_group *vg);
    734 uint64_t vg_max_pv(const struct volume_group *vg);
    735 uint64_t vg_max_lv(const struct volume_group *vg);
    736 uint32_t vg_mda_count(const struct volume_group *vg);
    737 int vg_check_write_mode(struct volume_group *vg);
    738 #define vg_is_clustered(vg) (vg_status((vg)) & CLUSTERED)
    739 #define vg_is_exported(vg) (vg_status((vg)) & EXPORTED_VG)
    740 #define vg_is_resizeable(vg) (vg_status((vg)) & RESIZEABLE_VG)
    741 
    742 int lv_has_unknown_segments(const struct logical_volume *lv);
    743 int vg_has_unknown_segments(const struct volume_group *vg);
    744 
    745 struct vgcreate_params {
    746 	char *vg_name;
    747 	uint32_t extent_size;
    748 	size_t max_pv;
    749 	size_t max_lv;
    750 	alloc_policy_t alloc;
    751 	int clustered; /* FIXME: put this into a 'status' variable instead? */
    752 };
    753 
    754 int vgcreate_params_validate(struct cmd_context *cmd,
    755 			     struct vgcreate_params *vp);
    756 
    757 int validate_vg_rename_params(struct cmd_context *cmd,
    758 			      const char *vg_name_old,
    759 			      const char *vg_name_new);
    760 #endif
    761