2003-09-15 22:22:50 +04:00
/*
2004-03-30 23:35:44 +04:00
* Copyright ( C ) 2003 - 2004 Sistina Software , Inc . All rights reserved .
2012-01-26 02:37:48 +04:00
* Copyright ( C ) 2004 - 2012 Red Hat , Inc . All rights reserved .
2003-09-15 22:22:50 +04:00
*
2004-03-30 23:35:44 +04:00
* 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
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2003-09-15 22:22:50 +04:00
*/
# ifndef _LVM_LV_ALLOC_H
2012-01-26 02:37:48 +04:00
# define _LVM_LV_ALLOC_H
2003-09-15 22:22:50 +04:00
2012-01-26 02:26:33 +04:00
# include "metadata-exported.h"
2011-10-23 20:02:01 +04:00
struct lv_segment * alloc_lv_segment ( const struct segment_type * segtype ,
2005-04-22 19:44:00 +04:00
struct logical_volume * lv ,
uint32_t le , uint32_t len ,
2009-11-25 01:55:55 +03:00
uint64_t status ,
2005-04-22 19:44:00 +04:00
uint32_t stripe_size ,
2005-06-01 20:51:55 +04:00
struct logical_volume * log_lv ,
2005-04-22 19:44:00 +04:00
uint32_t area_count ,
uint32_t area_len ,
uint32_t chunk_size ,
2005-06-01 20:51:55 +04:00
uint32_t region_size ,
2010-04-08 04:28:57 +04:00
uint32_t extents_copied ,
struct lv_segment * pvmove_source_seg ) ;
2005-04-22 19:44:00 +04:00
2005-05-03 21:28:23 +04:00
int set_lv_segment_area_pv ( struct lv_segment * seg , uint32_t area_num ,
struct physical_volume * pv , uint32_t pe ) ;
2008-01-16 22:00:59 +03:00
int set_lv_segment_area_lv ( struct lv_segment * seg , uint32_t area_num ,
struct logical_volume * lv , uint32_t le ,
2009-12-04 20:48:32 +03:00
uint64_t status ) ;
2005-06-14 21:54:48 +04:00
int move_lv_segment_area ( struct lv_segment * seg_to , uint32_t area_to ,
struct lv_segment * seg_from , uint32_t area_from ) ;
2012-06-27 22:37:54 +04:00
int release_lv_segment_area ( struct lv_segment * seg , uint32_t s ,
uint32_t area_reduction ) ;
2012-06-28 00:53:02 +04:00
int release_and_discard_lv_segment_area ( struct lv_segment * seg , uint32_t s , uint32_t area_reduction ) ;
2005-04-22 19:43:02 +04:00
2005-06-01 20:51:55 +04:00
struct alloc_handle ;
struct alloc_handle * allocate_extents ( struct volume_group * vg ,
struct logical_volume * lv ,
2006-05-10 01:23:51 +04:00
const struct segment_type * segtype ,
2005-06-01 20:51:55 +04:00
uint32_t stripes ,
uint32_t mirrors , uint32_t log_count ,
2008-12-19 18:24:52 +03:00
uint32_t log_region_size , uint32_t extents ,
2008-11-04 01:14:30 +03:00
struct dm_list * allocatable_pvs ,
2014-02-14 07:10:28 +04:00
alloc_policy_t alloc , int approx_alloc ,
2008-11-04 01:14:30 +03:00
struct dm_list * parallel_areas ) ;
2005-06-01 20:51:55 +04:00
int lv_add_segment ( struct alloc_handle * ah ,
uint32_t first_area , uint32_t num_areas ,
struct logical_volume * lv ,
2006-05-10 01:23:51 +04:00
const struct segment_type * segtype ,
2005-06-01 20:51:55 +04:00
uint32_t stripe_size ,
2009-11-25 01:55:55 +03:00
uint64_t status ,
2010-03-01 23:00:20 +03:00
uint32_t region_size ) ;
2005-06-01 20:51:55 +04:00
2007-12-20 18:42:55 +03:00
int lv_add_mirror_areas ( struct alloc_handle * ah ,
struct logical_volume * lv , uint32_t le ,
uint32_t region_size ) ;
pvmove: Enable all-or-nothing (atomic) pvmoves
pvmove can be used to move single LVs by name or multiple LVs that
lie within the specified PV range (e.g. /dev/sdb1:0-1000). When
moving more than one LV, the portions of those LVs that are in the
range to be moved are added to a new temporary pvmove LV. The LVs
then point to the range in the pvmove LV, rather than the PV
range.
Example 1:
We have two LVs in this example. After they were
created, the first LV was grown, yeilding two segments
in LV1. So, there are two LVs with a total of three
segments.
Before pvmove:
--------- --------- ---------
| LV1s0 | | LV2s0 | | LV1s1 |
--------- --------- ---------
| | |
-------------------------------------
PV | 000 - 255 | 256 - 511 | 512 - 767 |
-------------------------------------
After pvmove inserts the temporary pvmove LV:
--------- --------- ---------
| LV1s0 | | LV2s0 | | LV1s1 |
--------- --------- ---------
| | |
-------------------------------------
pvmove0 | seg 0 | seg 1 | seg 2 |
-------------------------------------
| | |
-------------------------------------
PV | 000 - 255 | 256 - 511 | 512 - 767 |
-------------------------------------
Each of the affected LV segments now point to a
range of blocks in the pvmove LV, which purposefully
corresponds to the segments moved from the original
LVs into the temporary pvmove LV.
The current implementation goes on from here to mirror the temporary
pvmove LV by segment. Further, as the pvmove LV is activated, only
one of its segments is actually mirrored (i.e. "moving") at a time.
The rest are either complete or not addressed yet. If the pvmove
is aborted, those segments that are completed will remain on the
destination and those that are not yet addressed or in the process
of moving will stay on the source PV. Thus, it is possible to have
a partially completed move - some LVs (or certain segments of LVs)
on the source PV and some on the destination.
Example 2:
What 'example 1' might look if it was half-way
through the move.
--------- --------- ---------
| LV1s0 | | LV2s0 | | LV1s1 |
--------- --------- ---------
| | |
-------------------------------------
pvmove0 | seg 0 | seg 1 | seg 2 |
-------------------------------------
| | |
| -------------------------
source PV | | 256 - 511 | 512 - 767 |
| -------------------------
| ||
-------------------------
dest PV | 000 - 255 | 256 - 511 |
-------------------------
This update allows the user to specify that they would like the
pvmove mirror created "by LV" rather than "by segment". That is,
the pvmove LV becomes an image in an encapsulating mirror along
with the allocated copy image.
Example 3:
A pvmove that is performed "by LV" rather than "by segment".
--------- ---------
| LV1s0 | | LV2s0 |
--------- ---------
| |
-------------------------
pvmove0 | * LV-level mirror * |
-------------------------
/ \
pvmove_mimage0 / pvmove_mimage1
------------------------- -------------------------
| seg 0 | seg 1 | | seg 0 | seg 1 |
------------------------- -------------------------
| | | |
------------------------- -------------------------
| 000 - 255 | 256 - 511 | | 000 - 255 | 256 - 511 |
------------------------- -------------------------
source PV dest PV
The thing that differentiates a pvmove done in this way and a simple
"up-convert" from linear to mirror is the preservation of the
distinct segments. A normal up-convert would simply allocate the
necessary space with no regard for segment boundaries. The pvmove
operation must preserve the segments because they are the critical
boundary between the segments of the LVs being moved. So, when the
pvmove copy image is allocated, all corresponding segments must be
allocated. The code that merges ajoining segments that are part of
the same LV when the metadata is written must also be avoided in
this case. This method of mirroring is unique enough to warrant its
own definitional macro, MIRROR_BY_SEGMENTED_LV. This joins the two
existing macros: MIRROR_BY_SEG (for original pvmove) and MIRROR_BY_LV
(for user created mirrors).
The advantages of performing pvmove in this way is that all of the
LVs affected can be moved together. It is an all-or-nothing approach
that leaves all LV segments on the source PV if the move is aborted.
Additionally, a mirror log can be used (in the future) to provide tracking
of progress; allowing the copy to continue where it left off in the event
there is a deactivation.
2014-06-18 07:59:36 +04:00
int lv_add_segmented_mirror_image ( struct alloc_handle * ah ,
struct logical_volume * lv , uint32_t le ,
uint32_t region_size ) ;
2007-12-20 18:42:55 +03:00
int lv_add_mirror_lvs ( struct logical_volume * lv ,
struct logical_volume * * sub_lvs ,
uint32_t num_extra_areas ,
2009-11-25 01:55:55 +03:00
uint64_t status , uint32_t region_size ) ;
2007-12-20 18:42:55 +03:00
2010-03-27 01:15:43 +03:00
int lv_add_log_segment ( struct alloc_handle * ah , uint32_t first_area ,
struct logical_volume * log_lv , uint64_t status ) ;
2009-11-25 01:55:55 +03:00
int lv_add_virtual_segment ( struct logical_volume * lv , uint64_t status ,
2014-10-26 10:13:59 +03:00
uint32_t extents , const struct segment_type * segtype ) ;
2005-06-01 20:51:55 +04:00
void alloc_destroy ( struct alloc_handle * ah ) ;
2011-07-19 20:37:42 +04:00
struct dm_list * build_parallel_areas_from_lv ( struct logical_volume * lv ,
2014-06-26 06:20:41 +04:00
unsigned use_pvmove_parent_lv ,
unsigned create_single_list ) ;
2005-11-24 23:58:44 +03:00
2003-09-15 22:22:50 +04:00
# endif